Merge vk-gl-cts/vulkan-cts-1.2.0 into vk-gl-cts/vulkan-cts-1.2.1
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gl / gl4cDirectStateAccessFramebuffersAndRenderbuffersTests.cpp
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  gl4cDirectStateAccessFramebuffersAndRenderbuffersTests.cpp
27  * \brief Conformance tests for the Direct State Access feature functionality (Framebuffers and Renderbuffer 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 #include <algorithm>
50 #include <climits>
51 #include <cmath>
52 #include <set>
53 #include <sstream>
54 #include <stack>
55 #include <string>
56 #include <vector>
57
58 namespace gl4cts
59 {
60 namespace DirectStateAccess
61 {
62 namespace Framebuffers
63 {
64 /******************************** Framebuffer Creation Test Implementation   ********************************/
65
66 /** @brief Creation Test constructor.
67  *
68  *  @param [in] context     OpenGL context.
69  */
70 CreationTest::CreationTest(deqp::Context& context)
71         : deqp::TestCase(context, "framebuffers_creation", "Framebuffer Objects Creation Test")
72 {
73         /* Intentionally left blank. */
74 }
75
76 /** @brief Iterate Creation Test cases.
77  *
78  *  @return Iteration result.
79  */
80 tcu::TestNode::IterateResult CreationTest::iterate()
81 {
82         /* Shortcut for GL functionality. */
83         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
84
85         /* Get context setup. */
86         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
87         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
88
89         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
90         {
91                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
92
93                 return STOP;
94         }
95
96         /* Running tests. */
97         bool is_ok      = true;
98         bool is_error = false;
99
100         /* Framebuffers' objects */
101         static const glw::GLuint framebuffers_count = 2;
102
103         glw::GLuint framebuffers_legacy[framebuffers_count] = {};
104         glw::GLuint framebuffers_dsa[framebuffers_count]        = {};
105
106         try
107         {
108                 /* Check legacy state creation. */
109                 gl.genFramebuffers(framebuffers_count, framebuffers_legacy);
110                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
111
112                 for (glw::GLuint i = 0; i < framebuffers_count; ++i)
113                 {
114                         if (gl.isFramebuffer(framebuffers_legacy[i]))
115                         {
116                                 is_ok = false;
117
118                                 /* Log. */
119                                 m_context.getTestContext().getLog()
120                                         << tcu::TestLog::Message
121                                         << "GenFramebuffers has created default objects, but it should create only a names."
122                                         << tcu::TestLog::EndMessage;
123                         }
124                 }
125
126                 /* Check direct state creation. */
127                 gl.createFramebuffers(framebuffers_count, framebuffers_dsa);
128                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");
129
130                 for (glw::GLuint i = 0; i < framebuffers_count; ++i)
131                 {
132                         if (!gl.isFramebuffer(framebuffers_dsa[i]))
133                         {
134                                 is_ok = false;
135
136                                 /* Log. */
137                                 m_context.getTestContext().getLog() << tcu::TestLog::Message
138                                                                                                         << "CreateFramebuffers has not created default objects."
139                                                                                                         << tcu::TestLog::EndMessage;
140                         }
141                 }
142         }
143         catch (...)
144         {
145                 is_ok   = false;
146                 is_error = true;
147         }
148
149         /* Cleanup. */
150         for (glw::GLuint i = 0; i < framebuffers_count; ++i)
151         {
152                 if (framebuffers_legacy[i])
153                 {
154                         gl.deleteFramebuffers(1, &framebuffers_legacy[i]);
155
156                         framebuffers_legacy[i] = 0;
157                 }
158
159                 if (framebuffers_dsa[i])
160                 {
161                         gl.deleteFramebuffers(1, &framebuffers_dsa[i]);
162
163                         framebuffers_dsa[i] = 0;
164                 }
165         }
166
167         /* Errors clean up. */
168         while (gl.getError())
169                 ;
170
171         /* Result's setup. */
172         if (is_ok)
173         {
174                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
175         }
176         else
177         {
178                 if (is_error)
179                 {
180                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
181                 }
182                 else
183                 {
184                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
185                 }
186         }
187
188         return STOP;
189 }
190
191 /******************************** Framebuffer Renderbuffer Attachment Test Implementation   ********************************/
192
193 /** @brief Framebuffer Renderbuffer Attachment Test constructor.
194  *
195  *  @param [in] context     OpenGL context.
196  */
197 RenderbufferAttachmentTest::RenderbufferAttachmentTest(deqp::Context& context)
198         : deqp::TestCase(context, "framebuffers_renderbuffer_attachment", "Framebuffer Renderbuffer Attachment Test")
199         , m_fbo(0)
200         , m_rbo(0)
201 {
202         /* Intentionally left blank. */
203 }
204
205 /** @brief Iterate Framebuffer Renderbuffer Attachment Test cases.
206  *
207  *  @return Iteration result.
208  */
209 tcu::TestNode::IterateResult RenderbufferAttachmentTest::iterate()
210 {
211         /* Shortcut for GL functionality. */
212         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
213
214         /* Get context setup. */
215         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
216         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
217
218         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
219         {
220                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
221
222                 return STOP;
223         }
224
225         /* Running tests. */
226         bool is_ok      = true;
227         bool is_error = false;
228
229         try
230         {
231                 glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;
232
233                 gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
234                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
235
236                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
237                 {
238                         is_ok &= Test(GL_COLOR_ATTACHMENT0 + i, GL_RGBA8);
239                         Clean();
240                 }
241
242                 is_ok &= Test(GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
243                 Clean();
244
245                 is_ok &= Test(GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
246                 Clean();
247
248                 is_ok &= Test(GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
249                 Clean();
250         }
251         catch (...)
252         {
253                 is_ok   = false;
254                 is_error = true;
255         }
256
257         /* Cleanup. */
258         Clean();
259
260         /* Result's setup. */
261         if (is_ok)
262         {
263                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
264         }
265         else
266         {
267                 if (is_error)
268                 {
269                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
270                 }
271                 else
272                 {
273                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
274                 }
275         }
276
277         return STOP;
278 }
279
280 /** @brief Test functionality.
281  *
282  *  @param [in] attachment         Framebuffer attachment.
283  *  @param [in] internalformat     Internal format.
284  *
285  *  @return True if test succeeded, false otherwise.
286  */
287 bool RenderbufferAttachmentTest::Test(glw::GLenum attachment, glw::GLenum internalformat)
288 {
289         /* Shortcut for GL functionality. */
290         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
291
292         /* RBO creation. */
293         gl.genRenderbuffers(1, &m_rbo);
294         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
295
296         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
297         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
298
299         gl.renderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
300         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
301
302         gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
303         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
304
305         /* FBO creation. */
306         gl.createFramebuffers(1, &m_fbo);
307         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");
308
309         gl.namedFramebufferRenderbuffer(m_fbo, attachment, GL_RENDERBUFFER, m_rbo);
310
311         if (glw::GLenum error = gl.getError())
312         {
313                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "NamedFramebufferRenderbuffer for "
314                                                                                         << glu::getFramebufferAttachmentStr(attachment)
315                                                                                         << " attachment failed with error value " << glu::getErrorStr(error) << "."
316                                                                                         << tcu::TestLog::EndMessage;
317
318                 return false;
319         }
320
321         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
322         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
323
324         glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
325
326         if (GL_FRAMEBUFFER_COMPLETE != status)
327         {
328                 m_context.getTestContext().getLog()
329                         << tcu::TestLog::Message << "Named Framebuffer Renderbuffer Attachment test failed because of framebuffer "
330                         << glu::getFramebufferStatusStr(status) << " with renderbuffer set up as "
331                         << glu::getFramebufferAttachmentStr(attachment) << " attachment." << tcu::TestLog::EndMessage;
332
333                 return false;
334         }
335
336         return true;
337 }
338
339 /** @brief Clean up GL state.
340  */
341 void RenderbufferAttachmentTest::Clean()
342 {
343         /* Shortcut for GL functionality. */
344         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
345
346         /* Cleanup. */
347         if (m_fbo)
348         {
349                 gl.deleteFramebuffers(1, &m_fbo);
350
351                 m_fbo = 0;
352         }
353
354         if (m_rbo)
355         {
356                 gl.deleteRenderbuffers(1, &m_rbo);
357
358                 m_rbo = 0;
359         }
360
361         /* Errors clean up. */
362         while (gl.getError())
363                 ;
364 }
365
366 /******************************** Framebuffer Texture Attachment Test Implementation   ********************************/
367
368 /** @brief Creation Test constructor.
369  *
370  *  @param [in] context     OpenGL context.
371  */
372 TextureAttachmentTest::TextureAttachmentTest(deqp::Context& context)
373         : deqp::TestCase(context, "framebuffers_texture_attachment", "Framebuffer Texture Attachment Test")
374         , m_fbo(0)
375         , m_to(0)
376 {
377         /* Intentionally left blank. */
378 }
379
380 /** @brief Iterate Creation Test cases.
381  *
382  *  @return Iteration result.
383  */
384 tcu::TestNode::IterateResult TextureAttachmentTest::iterate()
385 {
386         /* Shortcut for GL functionality. */
387         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
388
389         /* Get context setup. */
390         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
391         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
392
393         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
394         {
395                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
396
397                 return STOP;
398         }
399
400         /* Running tests. */
401         bool is_ok      = true;
402         bool is_error = false;
403
404         try
405         {
406                 glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;
407
408                 gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
409                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
410
411                 for (glw::GLuint i = 0; i < s_targets_count; ++i)
412                 {
413                         for (glw::GLuint j = 1; j <= MaxTextureLevels(s_targets[i]); ++j)
414                         {
415                                 for (glw::GLint k = 0; k < max_color_attachments; ++k)
416                                 {
417                                         is_ok &= Test(GL_COLOR_ATTACHMENT0 + k, true, s_targets[i], GL_RGBA8, j);
418                                         Clean();
419                                 }
420
421                                 is_ok &= Test(GL_DEPTH_ATTACHMENT, false, s_targets[i], GL_DEPTH_COMPONENT24, j);
422                                 Clean();
423
424                                 is_ok &= Test(GL_STENCIL_ATTACHMENT, false, s_targets[i], GL_STENCIL_INDEX8, j);
425                                 Clean();
426
427                                 is_ok &= Test(GL_DEPTH_STENCIL_ATTACHMENT, false, s_targets[i], GL_DEPTH24_STENCIL8, j);
428                                 Clean();
429                         }
430                 }
431         }
432         catch (...)
433         {
434                 is_ok   = false;
435                 is_error = true;
436         }
437
438         /* Cleanup. */
439         Clean();
440
441         /* Result's setup. */
442         if (is_ok)
443         {
444                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
445         }
446         else
447         {
448                 if (is_error)
449                 {
450                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
451                 }
452                 else
453                 {
454                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
455                 }
456         }
457
458         return STOP;
459 }
460
461 /** @brief Test functionality.
462  *
463  *  @param [in]  attachment            Framebuffer attachment.
464  *  @param [in] is_color_attachment    Is color attachment tested.
465  *  @param [in] texture_target         Texture target.
466  *  @param [in] internalformat         Internal format ot be tested.
467  *  @param [in] levels                 Number of levels.
468  *
469  *  @return True if test succeeded, false otherwise.
470  */
471 bool TextureAttachmentTest::Test(glw::GLenum attachment, bool is_color_attachment, glw::GLenum texture_target,
472                                                                  glw::GLenum internalformat, glw::GLuint levels)
473 {
474         /* Shortcut for GL functionality. */
475         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
476
477         /* RBO creation. */
478         gl.genTextures(1, &m_to);
479         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
480
481         gl.bindTexture(texture_target, m_to);
482         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
483
484         if (GL_TEXTURE_2D_MULTISAMPLE == texture_target)
485         {
486                 gl.texStorage2DMultisample(texture_target, 1, internalformat, (glw::GLuint)std::pow((double)2, (double)levels),
487                                                                    (glw::GLuint)std::pow((double)2, (double)levels), GL_FALSE);
488                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
489         }
490         else
491         {
492                 gl.texStorage2D(texture_target, levels, internalformat, (glw::GLuint)std::pow((double)2, (double)levels),
493                                                 (glw::GLuint)std::pow((double)2, (double)levels));
494                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
495         }
496
497         gl.bindTexture(texture_target, 0);
498         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
499
500         /* FBO creation. */
501         gl.createFramebuffers(1, &m_fbo);
502         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");
503
504         for (glw::GLuint i = 0; i < levels; ++i)
505         {
506                 gl.namedFramebufferTexture(m_fbo, attachment, m_to, i);
507
508                 SubTestAttachmentError(attachment, texture_target, i, levels);
509
510                 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
511                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
512
513                 if (is_color_attachment)
514                 {
515                         gl.drawBuffer(attachment);
516                         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");
517
518                         gl.readBuffer(attachment);
519                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer has failed");
520                 }
521
522                 SubTestStatus(attachment, texture_target, i, levels);
523
524                 if (GL_TEXTURE_2D_MULTISAMPLE != texture_target)
525                 {
526                         Clear();
527
528                         if (!SubTestContent(attachment, texture_target, internalformat, i, levels))
529                         {
530                                 return false;
531                         }
532                 }
533
534                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
535                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
536         }
537
538         return true;
539 }
540
541 /** @brief Check error and log.
542  *
543  *  @param [in] attachment             Framebuffer attachment.
544  *  @param [in] texture_target         Texture target.
545  *  @param [in] level                  Tested level.
546  *  @param [in] levels                 Number of levels.
547  *
548  *  @return True if no error, false otherwise.
549  */
550 bool TextureAttachmentTest::SubTestAttachmentError(glw::GLenum attachment, glw::GLenum texture_target,
551                                                                                                    glw::GLuint level, glw::GLuint levels)
552 {
553         /* Shortcut for GL functionality. */
554         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
555
556         if (glw::GLenum error = gl.getError())
557         {
558                 m_context.getTestContext().getLog()
559                         << tcu::TestLog::Message << "NamedFramebufferTexture for " << glu::getFramebufferAttachmentStr(attachment)
560                         << " attachment of " << glu::getTextureTargetStr(texture_target) << " texture and texture level " << level
561                         << " of texture with " << levels << " levels failed with error value " << glu::getErrorStr(error) << "."
562                         << tcu::TestLog::EndMessage;
563
564                 return false;
565         }
566
567         return true;
568 }
569
570 /** @brief Check status and log.
571  *
572  *  @param [in] attachment             Framebuffer attachment.
573  *  @param [in] texture_target         Texture target.
574  *  @param [in] level                  Tested level.
575  *  @param [in] levels                 Number of levels.
576  *
577  *  @return True if FRAMEBUFFER_COMPLETE, false otherwise.
578  */
579 bool TextureAttachmentTest::SubTestStatus(glw::GLenum attachment, glw::GLenum texture_target, glw::GLuint level,
580                                                                                   glw::GLuint levels)
581 {
582         /* Shortcut for GL functionality. */
583         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
584
585         glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
586
587         if (GL_FRAMEBUFFER_COMPLETE != status)
588         {
589                 m_context.getTestContext().getLog()
590                         << tcu::TestLog::Message << "Named Framebuffer Texture Attachment test failed because of framebuffer "
591                         << glu::getFramebufferStatusStr(status) << " status with " << glu::getTextureTargetStr(texture_target)
592                         << " texture set up as " << glu::getFramebufferAttachmentStr(attachment) << " attachment and texture level "
593                         << level << " of texture with " << levels << " levels." << tcu::TestLog::EndMessage;
594
595                 return false;
596         }
597
598         return true;
599 }
600
601 /** @brief Check framebuffer content and log.
602  *
603  *  @param [in] attachment             Framebuffer attachment.
604  *  @param [in] texture_target         Texture target.
605  *  @param [in] internalformat         Tested internal format.
606  *  @param [in] level                  Tested level.
607  *  @param [in] levels                 Number of levels.
608  *
609  *  @return True if FRAMEBUFFER_COMPLETE, false otherwise.
610  */
611 bool TextureAttachmentTest::SubTestContent(glw::GLenum attachment, glw::GLenum texture_target,
612                                                                                    glw::GLenum internalformat, glw::GLuint level, glw::GLuint levels)
613 {
614         /* Shortcut for GL functionality. */
615         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
616
617         /* Check framebuffer's color content. */
618         if (GL_RGBA8 == internalformat)
619         {
620                 glw::GLfloat color[4] = { 0.f };
621
622                 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, color);
623                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
624
625                 for (int i = 0; i < 4 /* color components */; ++i)
626                 {
627                         if (de::abs(s_reference_color[i] - color[i]) > 0.0625 /* precision */)
628                         {
629                                 m_context.getTestContext().getLog()
630                                         << tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed with "
631                                         << glu::getTextureTargetStr(texture_target) << " texture set up as "
632                                         << glu::getFramebufferAttachmentStr(attachment) << " attachment and texture level " << level
633                                         << " of texture with " << levels << " levels. The color content of the framebuffer was ["
634                                         << color[0] << ", " << color[1] << ", " << color[2] << ", " << color[3] << "], but ["
635                                         << s_reference_color[0] << ", " << s_reference_color[1] << ", " << s_reference_color[2] << ", "
636                                         << s_reference_color[3] << "] was expected." << tcu::TestLog::EndMessage;
637
638                                 return false;
639                         }
640                 }
641         }
642
643         /* Check framebuffer's depth content. */
644         if ((GL_DEPTH_COMPONENT24 == internalformat) || (GL_DEPTH24_STENCIL8 == internalformat))
645         {
646                 glw::GLfloat depth = 0.f;
647
648                 gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
649                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
650
651                 if (de::abs(s_reference_depth - depth) > 0.0625 /* precision */)
652                 {
653                         m_context.getTestContext().getLog()
654                                 << tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed "
655                                 << "with texture set up as " << glu::getFramebufferAttachmentStr(attachment)
656                                 << " attachment and texture level " << level << " of texture with " << levels
657                                 << " levels. The depth content of the framebuffer was [" << depth << "], but [" << s_reference_depth
658                                 << "] was expected." << tcu::TestLog::EndMessage;
659
660                         return false;
661                 }
662         }
663
664         /* Check framebuffer's stencil content. */
665         if ((GL_STENCIL_INDEX8 == internalformat) || (GL_DEPTH24_STENCIL8 == internalformat))
666         {
667                 glw::GLint stencil = 0;
668
669                 gl.readPixels(0, 0, 1, 1, GL_STENCIL_INDEX, GL_INT, &stencil);
670                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
671
672                 if (s_reference_stencil != stencil)
673                 {
674                         m_context.getTestContext().getLog()
675                                 << tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed "
676                                 << "with texture set up as " << glu::getFramebufferAttachmentStr(attachment)
677                                 << " attachment and texture level " << level << " of texture with " << levels
678                                 << " levels. The stencil content of the framebuffer was [" << stencil << "], but ["
679                                 << s_reference_stencil << "] was expected." << tcu::TestLog::EndMessage;
680
681                         return false;
682                 }
683         }
684
685         return true;
686 }
687
688 /** @brief Query max texture levels.
689  *
690  *  @param [in] texture_target         Texture target.
691  *
692  *  @return Max texture levels.
693  */
694 glw::GLuint TextureAttachmentTest::MaxTextureLevels(glw::GLenum texture_target)
695 {
696         /* Shortcut for GL functionality. */
697         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
698
699         glw::GLint max_texture_size = 1024 /* Specification default. */;
700
701         switch (texture_target)
702         {
703         case GL_TEXTURE_RECTANGLE:
704         case GL_TEXTURE_2D_MULTISAMPLE:
705                 return 1;
706
707         case GL_TEXTURE_2D:
708                 gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
709                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
710
711                 return (glw::GLuint)std::log((double)max_texture_size);
712
713         case GL_TEXTURE_CUBE_MAP:
714                 gl.getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_texture_size);
715                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
716
717                 return (glw::GLuint)std::log((double)max_texture_size);
718
719         default:
720                 throw 0;
721         }
722
723         /* For compiler warnings only. */
724         return 0;
725 }
726
727 /** @brief Clear texture.
728  */
729 void TextureAttachmentTest::Clear()
730 {
731         /* Shortcut for GL functionality. */
732         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
733
734         /* Setup clear values. */
735         gl.clearColor(s_reference_color[0], s_reference_color[1], s_reference_color[2], s_reference_color[3]);
736         gl.clearDepth(s_reference_depth);
737         gl.clearStencil(s_reference_stencil);
738
739         /* Clear rbo/fbo. */
740         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
741 }
742
743 /** @brief Clean up GL state.
744  */
745 void TextureAttachmentTest::Clean()
746 {
747         /* Shortcut for GL functionality. */
748         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
749
750         /* Cleanup. */
751         if (m_fbo)
752         {
753                 gl.deleteFramebuffers(1, &m_fbo);
754
755                 m_fbo = 0;
756         }
757
758         if (m_to)
759         {
760                 gl.deleteTextures(1, &m_to);
761
762                 m_to = 0;
763         }
764
765         /* Returning to default clear values. */
766         gl.clearColor(0.f, 0.f, 0.f, 0.f);
767         gl.clearDepth(1.f);
768         gl.clearStencil(0);
769
770         /* Errors clean up. */
771         while (gl.getError())
772                 ;
773 }
774
775 /** Tested targets. */
776 const glw::GLenum TextureAttachmentTest::s_targets[] = { GL_TEXTURE_RECTANGLE, GL_TEXTURE_2D, GL_TEXTURE_2D_MULTISAMPLE,
777                                                                                                                  GL_TEXTURE_CUBE_MAP };
778
779 /** Tested targets count. */
780 const glw::GLuint TextureAttachmentTest::s_targets_count = sizeof(s_targets) / sizeof(s_targets[0]);
781
782 const glw::GLfloat TextureAttachmentTest::s_reference_color[4]             = { 0.25, 0.5, 0.75, 1.0 }; //!< Reference color.
783 const glw::GLint   TextureAttachmentTest::s_reference_color_integer[4] = { 1, 2, 3,
784                                                                                                                                                  4 }; //!< Reference color for integer format.
785 const glw::GLfloat TextureAttachmentTest::s_reference_depth   = 0.5;              //!< Reference depth value.
786 const glw::GLint   TextureAttachmentTest::s_reference_stencil = 7;                        //!< Reference stencil value.
787
788 /******************************** Framebuffer Texture Layer Attachment Test Implementation   ********************************/
789
790 /** @brief Framebuffer Texture Layer Attachment Test constructor.
791  *
792  *  @param [in] context     OpenGL context.
793  */
794 TextureLayerAttachmentTest::TextureLayerAttachmentTest(deqp::Context& context)
795         : deqp::TestCase(context, "framebuffers_texture_layer_attachment", "Framebuffer Texture Layer Attachment Test")
796         , m_fbo(0)
797         , m_to(0)
798 {
799         /* Intentionally left blank. */
800 }
801
802 /** @brief Iterate Framebuffer Texture Layer Attachment Test cases.
803  *
804  *  @return Iteration result.
805  */
806 tcu::TestNode::IterateResult TextureLayerAttachmentTest::iterate()
807 {
808         /* Shortcut for GL functionality. */
809         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
810
811         /* Get context setup. */
812         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
813         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
814
815         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
816         {
817                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
818
819                 return STOP;
820         }
821
822         /* Running tests. */
823         bool is_ok      = true;
824         bool is_error = false;
825
826         try
827         {
828                 glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;
829
830                 gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
831                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
832
833                 for (glw::GLuint i = 0; i < s_targets_count; ++i)
834                 {
835                         glw::GLuint layers_counts[] = { (GL_TEXTURE_CUBE_MAP_ARRAY == (glw::GLuint)s_targets[i]) ? 6u : 1u,
836                                                                                         (GL_TEXTURE_CUBE_MAP_ARRAY == (glw::GLuint)s_targets[i]) ? 192u : 192u,
837                                                                                         MaxTextureLayers(s_targets[i]) };
838
839                         glw::GLuint layers_counts_count = sizeof(layers_counts) / sizeof(layers_counts[0]);
840
841                         for (glw::GLuint j = 1; j <= MaxTextureLevels(s_targets[i]); ++j)
842                         {
843                                 for (glw::GLuint k = 0; k < layers_counts_count; ++k)
844                                 {
845                                         for (glw::GLint l = 0; l < max_color_attachments; ++l)
846                                         {
847                                                 is_ok &= Test(GL_COLOR_ATTACHMENT0 + l, true, s_targets[i], GL_RGBA8, j, layers_counts[k]);
848                                                 Clean();
849                                         }
850
851                                         if (GL_TEXTURE_3D != s_targets[i])
852                                         {
853                                                 is_ok &=
854                                                         Test(GL_DEPTH_ATTACHMENT, false, s_targets[i], GL_DEPTH_COMPONENT24, j, layers_counts[k]);
855                                                 Clean();
856
857                                                 is_ok &= Test(GL_DEPTH_STENCIL_ATTACHMENT, false, s_targets[i], GL_DEPTH24_STENCIL8, j,
858                                                                           layers_counts[k]);
859                                                 Clean();
860
861                                                 is_ok &=
862                                                         Test(GL_STENCIL_ATTACHMENT, false, s_targets[i], GL_STENCIL_INDEX8, j, layers_counts[k]);
863                                                 Clean();
864                                         }
865                                 }
866                         }
867                 }
868         }
869         catch (...)
870         {
871                 is_ok   = false;
872                 is_error = true;
873         }
874
875         /* Cleanup. */
876         Clean();
877
878         /* Result's setup. */
879         if (is_ok)
880         {
881                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
882         }
883         else
884         {
885                 if (is_error)
886                 {
887                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
888                 }
889                 else
890                 {
891                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
892                 }
893         }
894
895         return STOP;
896 }
897
898 /** @brief Test texture layer attachment.
899  *
900  *  @param [in] attachment             Framebuffer attachment.
901  *  @param [in] is_color_attachment    Is color attachment tested.
902  *  @param [in] texture_target         Texture target.
903  *  @param [in] internalformat         Tested internal format.
904  *  @param [in] level                  Tested level.
905  *  @param [in] levels                 Number of levels.
906  *  @param [in] layers                 Number of layers.
907  *
908  *  @return True if test succeeded, false otherwise.
909  */
910 bool TextureLayerAttachmentTest::Test(glw::GLenum attachment, bool is_color_attachment, glw::GLenum texture_target,
911                                                                           glw::GLenum internalformat, glw::GLuint levels, glw::GLint layers)
912 {
913         /* Shortcut for GL functionality. */
914         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
915
916         /* RBO creation. */
917         gl.genTextures(1, &m_to);
918         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
919
920         gl.bindTexture(texture_target, m_to);
921         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
922
923         // Lower the layers count when multiple levels are requested to limit the amount of memory required
924         layers = deMax32(1, (glw::GLint)((deUint64)layers / (1ull<<(deUint64)(2*(levels-1)))));
925         if (GL_TEXTURE_CUBE_MAP_ARRAY == texture_target)
926         {
927                 layers = deMax32(6, (layers / 6) * 6);
928         }
929
930         if (GL_TEXTURE_2D_MULTISAMPLE_ARRAY == texture_target)
931         {
932                 gl.texStorage3DMultisample(texture_target, 1, internalformat, (glw::GLuint)std::pow((double)2, (double)levels),
933                                                                    (glw::GLuint)std::pow((double)2, (double)levels), layers, GL_FALSE);
934                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
935         }
936         else
937         {
938                 gl.texStorage3D(texture_target, levels, internalformat, (glw::GLuint)std::pow((double)2, (double)levels),
939                                                 (glw::GLuint)std::pow((double)2, (double)levels), layers);
940                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
941         }
942
943         gl.bindTexture(texture_target, 0);
944         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
945
946         /* FBO creation. */
947         gl.createFramebuffers(1, &m_fbo);
948         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");
949
950         for (glw::GLuint i = 0; i < levels; ++i)
951         {
952                 glw::GLuint j = 0;
953                 glw::GLuint k = 1;
954
955                 /* 3D textures are mipmapped also in depth directio, so number of layers to be tested must be limited. */
956                 glw::GLuint layers_at_level = (GL_TEXTURE_3D == texture_target) ?
957                                                                                   (de::min(layers, layers / (glw::GLint)std::pow(2.0, (double)i))) :
958                                                                                   layers;
959
960                 while (j < layers_at_level) /* Only layers with Fibonacci number index are tested to reduce the test time. */
961                 {
962                         /* Attach texture layer. */
963                         gl.namedFramebufferTextureLayer(m_fbo, attachment, m_to, i, j);
964
965                         if (!SubTestAttachmentError(attachment, texture_target, i, j, levels, layers))
966                         {
967                                 return false;
968                         }
969
970                         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
971                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
972
973                         if (is_color_attachment)
974                         {
975                                 gl.drawBuffer(attachment);
976                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");
977
978                                 gl.readBuffer(attachment);
979                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer has failed");
980                         }
981
982                         if (!SubTestStatus(attachment, texture_target, i, j, levels, layers))
983                         {
984                                 return false;
985                         }
986
987                         if (GL_TEXTURE_2D_MULTISAMPLE_ARRAY != texture_target)
988                         {
989                                 Clear();
990
991                                 if (!SubTestContent(attachment, texture_target, internalformat, i, j, levels, layers))
992                                 {
993                                         return false;
994                                 }
995                         }
996
997                         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
998                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
999
1000                         /* Fibonacci number iteration. */
1001                         int l = j;
1002                         j        = j + k;
1003                         k        = l;
1004                 }
1005         }
1006
1007         return true;
1008 }
1009
1010 /** @brief Check error and log.
1011  *
1012  *  @param [in] attachment             Framebuffer attachment.
1013  *  @param [in] texture_target         Texture target.
1014  *  @param [in] level                  Tested level.
1015  *  @param [in] layer                  Tested layer.
1016  *  @param [in] levels                 Number of levels.
1017  *  @param [in] layers                 Number of layers.
1018  *
1019  *  @return True if no error, false otherwise.
1020  */
1021 bool TextureLayerAttachmentTest::SubTestAttachmentError(glw::GLenum attachment, glw::GLenum texture_target,
1022                                                                                                                 glw::GLuint level, glw::GLint layer, glw::GLuint levels,
1023                                                                                                                 glw::GLint layers)
1024 {
1025         /* Shortcut for GL functionality. */
1026         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1027
1028         /* Check and log. */
1029         if (glw::GLenum error = gl.getError())
1030         {
1031                 m_context.getTestContext().getLog()
1032                         << tcu::TestLog::Message << "NamedFramebufferTexture for " << glu::getFramebufferAttachmentStr(attachment)
1033                         << " attachment of " << glu::getTextureTargetStr(texture_target) << " texture at level " << level
1034                         << " and at layer " << layer << " where texture has " << levels << " levels and " << layers
1035                         << " layers failed with error value " << glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
1036
1037                 return false;
1038         }
1039
1040         return true;
1041 }
1042
1043 /** @brief Check framebuffer completness.
1044  *
1045  *  @param [in] attachment             Framebuffer attachment.
1046  *  @param [in] texture_target         Texture target.
1047  *  @param [in] level                  Tested level.
1048  *  @param [in] layer                  Tested layer.
1049  *  @param [in] levels                 Number of levels.
1050  *  @param [in] layers                 Number of layers.
1051  *
1052  *  @return True if framebuffer is complete, false otherwise.
1053  */
1054 bool TextureLayerAttachmentTest::SubTestStatus(glw::GLenum attachment, glw::GLenum texture_target, glw::GLuint level,
1055                                                                                            glw::GLint layer, glw::GLuint levels, glw::GLint layers)
1056 {
1057         /* Shortcut for GL functionality. */
1058         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1059
1060         /* Check framebuffer status. */
1061         glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1062
1063         if (GL_FRAMEBUFFER_COMPLETE != status)
1064         {
1065                 m_context.getTestContext().getLog()
1066                         << tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed because of framebuffer "
1067                         << glu::getFramebufferStatusStr(status) << " with " << glu::getTextureTargetStr(texture_target)
1068                         << " texture set up as " << glu::getFramebufferAttachmentStr(attachment) << " attachment and texture level "
1069                         << level << " and texture layer " << layer << " of texture with " << levels << " levels and " << layers
1070                         << " layers." << tcu::TestLog::EndMessage;
1071
1072                 return false;
1073         }
1074
1075         return true;
1076 }
1077
1078 /** @brief Check framebuffer cntent.
1079  *
1080  *  @param [in] attachment             Framebuffer attachment.
1081  *  @param [in] texture_target         Texture target.
1082  *  @param [in] internalformat         Tested internal format.
1083  *  @param [in] level                  Tested level.
1084  *  @param [in] layer                  Tested layer.
1085  *  @param [in] levels                 Number of levels.
1086  *  @param [in] layers                 Number of layers.
1087  *
1088  *  @return True if framebuffer content is equal to the reference, false otherwise.
1089  */
1090 bool TextureLayerAttachmentTest::SubTestContent(glw::GLenum attachment, glw::GLenum texture_target,
1091                                                                                                 glw::GLenum internalformat, glw::GLuint level, glw::GLint layer,
1092                                                                                                 glw::GLuint levels, glw::GLint layers)
1093 {
1094         /* Shortcut for GL functionality. */
1095         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1096
1097         /* Check framebuffer's color content. */
1098         if (GL_RGBA8 == internalformat)
1099         {
1100                 glw::GLfloat color[4] = { 0.f };
1101
1102                 gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, color);
1103                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
1104
1105                 for (int i = 0; i < 4 /* color components */; ++i)
1106                 {
1107                         if (de::abs(s_reference_color[i] - color[i]) > 0.0625 /* precision */)
1108                         {
1109                                 m_context.getTestContext().getLog()
1110                                         << tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed with "
1111                                         << glu::getTextureTargetStr(texture_target) << " texture set up as "
1112                                         << glu::getFramebufferAttachmentStr(attachment) << " attachment and texture level " << level
1113                                         << " and texture layer " << layer << " of texture with " << levels << " levels and " << layers
1114                                         << " layers. The color content of the framebuffer was [" << color[0] << ", " << color[1] << ", "
1115                                         << color[2] << ", " << color[3] << "], but [" << s_reference_color[0] << ", "
1116                                         << s_reference_color[1] << ", " << s_reference_color[2] << ", " << s_reference_color[3]
1117                                         << "] was expected." << tcu::TestLog::EndMessage;
1118                                 return false;
1119                         }
1120                 }
1121         }
1122
1123         /* Check framebuffer's depth content. */
1124         if ((GL_DEPTH_COMPONENT24 == internalformat) || (GL_DEPTH24_STENCIL8 == internalformat))
1125         {
1126                 glw::GLfloat depth = 0.f;
1127
1128                 gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
1129                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
1130
1131                 if (de::abs(s_reference_depth - depth) > 0.0625 /* precision */)
1132                 {
1133                         m_context.getTestContext().getLog()
1134                                 << tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed "
1135                                 << "with texture set up as " << glu::getFramebufferAttachmentStr(attachment)
1136                                 << " attachment and texture level " << level << " and texture layer " << layer << " of texture with "
1137                                 << levels << " levels and " << layers << " layers. The depth content of the framebuffer was [" << depth
1138                                 << "], but [" << s_reference_depth << "] was expected." << tcu::TestLog::EndMessage;
1139
1140                         return false;
1141                 }
1142         }
1143
1144         /* Check framebuffer's stencil content. */
1145         if ((GL_STENCIL_INDEX8 == internalformat) || (GL_DEPTH24_STENCIL8 == internalformat))
1146         {
1147                 glw::GLint stencil = 0;
1148
1149                 gl.readPixels(0, 0, 1, 1, GL_STENCIL_INDEX, GL_INT, &stencil);
1150                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
1151
1152                 if (s_reference_stencil != stencil)
1153                 {
1154                         m_context.getTestContext().getLog()
1155                                 << tcu::TestLog::Message << "Named Framebuffer Texture Layer Attachment test failed "
1156                                 << "with texture set up as " << glu::getFramebufferAttachmentStr(attachment)
1157                                 << " attachment and texture level " << level << " and texture layer " << layer << " of texture with "
1158                                 << levels << " levels and " << layers << " layers. The stencil content of the framebuffer was ["
1159                                 << stencil << "], but [" << s_reference_stencil << "] was expected." << tcu::TestLog::EndMessage;
1160
1161                         return false;
1162                 }
1163         }
1164
1165         return true;
1166 }
1167
1168 /** @brief Clear framebuffer.
1169  */
1170 void TextureLayerAttachmentTest::Clear()
1171 {
1172         /* Shortcut for GL functionality. */
1173         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1174
1175         /* Setup clear values. */
1176         gl.clearColor(s_reference_color[0], s_reference_color[1], s_reference_color[2], s_reference_color[3]);
1177         gl.clearDepth(s_reference_depth);
1178         gl.clearStencil(s_reference_stencil);
1179
1180         /* Clear rbo/fbo. */
1181         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1182 }
1183
1184 /** @brief Query maximum number of texture levels.
1185  *
1186  *  @return True if max number of texture levels, false otherwise.
1187  */
1188 glw::GLuint TextureLayerAttachmentTest::MaxTextureLevels(glw::GLenum texture_target)
1189 {
1190         /* Shortcut for GL functionality. */
1191         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1192
1193         glw::GLint max_texture_size = 1024 /* Specification default. */;
1194
1195         switch (texture_target)
1196         {
1197         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1198                 return 1;
1199
1200         case GL_TEXTURE_2D_ARRAY:
1201
1202                 gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
1203                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
1204
1205                 return (glw::GLuint)std::log((double)max_texture_size);
1206
1207         case GL_TEXTURE_CUBE_MAP_ARRAY:
1208
1209                 gl.getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE , &max_texture_size);
1210                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
1211
1212                 return (glw::GLuint)std::log((double)max_texture_size);
1213
1214         case GL_TEXTURE_3D:
1215
1216                 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max_texture_size);
1217                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
1218
1219                 return (glw::GLuint)std::log((double)max_texture_size);
1220         default:
1221                 throw 0;
1222         }
1223
1224         /* For compiler warnings only. */
1225         return 0;
1226 }
1227
1228 /** @brief Query maximum number of texture layers.
1229  *
1230  *  @return True if max number of texture layers, false otherwise.
1231  */
1232 glw::GLuint TextureLayerAttachmentTest::MaxTextureLayers(glw::GLenum texture_target)
1233 {
1234         /* Shortcut for GL functionality. */
1235         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1236
1237         glw::GLint max_texture_size = 1024 /* Specification default. */;
1238
1239         switch (texture_target)
1240         {
1241         case GL_TEXTURE_3D:
1242                 gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max_texture_size);
1243                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
1244
1245                 return max_texture_size;
1246
1247         case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1248         case GL_TEXTURE_2D_ARRAY:
1249
1250                 gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max_texture_size);
1251                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
1252
1253                 return max_texture_size;
1254
1255         case GL_TEXTURE_CUBE_MAP_ARRAY:
1256                 gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max_texture_size);
1257                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
1258
1259                 return (max_texture_size / 6) * 6; /* Make sure that max_texture_size is dividable by 6 */
1260
1261         default:
1262                 throw 0;
1263         }
1264
1265         /* For compiler warnings only. */
1266         return 0;
1267 }
1268
1269 /** @brief Clean up GL state.
1270  */
1271 void TextureLayerAttachmentTest::Clean()
1272 {
1273         /* Shortcut for GL functionality. */
1274         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1275
1276         /* Cleanup. */
1277         if (m_fbo)
1278         {
1279                 gl.deleteFramebuffers(1, &m_fbo);
1280
1281                 m_fbo = 0;
1282         }
1283
1284         if (m_to)
1285         {
1286                 gl.deleteTextures(1, &m_to);
1287
1288                 m_to = 0;
1289         }
1290
1291         /* Returning to default clear values. */
1292         gl.clearColor(0.f, 0.f, 0.f, 0.f);
1293         gl.clearDepth(1.f);
1294         gl.clearStencil(0);
1295
1296         /* Errors clean up. */
1297         while (gl.getError())
1298                 ;
1299 }
1300
1301 const glw::GLenum TextureLayerAttachmentTest::s_targets[] = //!< Targets to be tested.
1302         { GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_3D };
1303
1304 const glw::GLuint TextureLayerAttachmentTest::s_targets_count =
1305         sizeof(s_targets) / sizeof(s_targets[0]); //!< Number of tested targets.
1306
1307 const glw::GLfloat TextureLayerAttachmentTest::s_reference_color[4] = { 0.25, 0.5, 0.75, 1.0 }; //!< Reference color.
1308 const glw::GLint   TextureLayerAttachmentTest::s_reference_color_integer[4] = { 1, 2, 3,
1309                                                                                                                                                           4 }; //!< Reference integer color.
1310 const glw::GLfloat TextureLayerAttachmentTest::s_reference_depth   = 0.5;                  //!< Reference depth.
1311 const glw::GLint   TextureLayerAttachmentTest::s_reference_stencil = 7;                    //!< Reference stencil index.
1312
1313 /******************************** Named Framebuffer Read / Draw Buffer Test Implementation   ********************************/
1314
1315 /** @brief Named Framebuffer Read / Draw Buffer Test constructor.
1316  *
1317  *  @param [in] context     OpenGL context.
1318  */
1319 DrawReadBufferTest::DrawReadBufferTest(deqp::Context& context)
1320         : deqp::TestCase(context, "framebuffers_read_draw_buffer", "Framebuffer Read and Draw Buffer Test")
1321 {
1322         /* Intentionally left blank. */
1323 }
1324
1325 /** @brief Iterate Named Framebuffer Read / Draw Buffer Test cases.
1326  *
1327  *  @return Iteration result.
1328  */
1329 tcu::TestNode::IterateResult DrawReadBufferTest::iterate()
1330 {
1331         /* Shortcut for GL functionality. */
1332         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1333
1334         /* Get context setup. */
1335         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1336         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1337
1338         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1339         {
1340                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1341
1342                 return STOP;
1343         }
1344
1345         /* Running tests. */
1346         bool is_ok      = true;
1347         bool is_error = false;
1348
1349         /* Framebuffers' objects */
1350         glw::GLuint framebuffer = 0;
1351
1352         /* Get number of color attachments. */
1353         glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;
1354
1355         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
1356         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
1357
1358         std::vector<glw::GLuint> renderbuffers(max_color_attachments);
1359
1360         for (glw::GLint i = 0; i < max_color_attachments; ++i)
1361         {
1362                 renderbuffers[i] = 0;
1363         }
1364
1365         try
1366         {
1367                 /* Prepare framebuffer... */
1368                 gl.genFramebuffers(1, &framebuffer);
1369                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
1370
1371                 gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1372                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
1373
1374                 gl.genRenderbuffers(max_color_attachments, &(renderbuffers[0]));
1375                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
1376
1377                 /* .. with renderbuffer color attachments. */
1378                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
1379                 {
1380                         gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
1381                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
1382
1383                         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
1384                         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
1385
1386                         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, renderbuffers[i]);
1387                         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
1388                 }
1389
1390                 /* Check that framebuffer is complete. */
1391                 if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
1392                 {
1393                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
1394                                                                                                 << tcu::TestLog::EndMessage;
1395
1396                         throw 0;
1397                 }
1398
1399                 /* Clear each of the framebuffer's attachments with unique color using NamedFramebufferDrawBuffer for attachment selection. */
1400                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
1401                 {
1402                         gl.clearColor((float)i / (float)max_color_attachments, (float)i / (float)max_color_attachments,
1403                                                   (float)i / (float)max_color_attachments, (float)i / (float)max_color_attachments);
1404                         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");
1405
1406                         gl.namedFramebufferDrawBuffer(framebuffer, GL_COLOR_ATTACHMENT0 + i);
1407
1408                         if (glw::GLenum error = gl.getError())
1409                         {
1410                                 m_context.getTestContext().getLog()
1411                                         << tcu::TestLog::Message << "NamedFramebufferDrawBuffer unexpectedly generated "
1412                                         << glu::getErrorStr(error) << " error with GL_COLOR_ATTACHMENT" << i << ". Test fails."
1413                                         << tcu::TestLog::EndMessage;
1414                                 is_ok = false;
1415                         }
1416
1417                         gl.clear(GL_COLOR_BUFFER_BIT);
1418                         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear has failed");
1419                 }
1420
1421                 /* Fetch framebuffer's content and compare it with reference using NamedFramebufferReadBuffer for attachment selection. */
1422                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
1423                 {
1424                         gl.namedFramebufferReadBuffer(framebuffer, GL_COLOR_ATTACHMENT0 + i);
1425
1426                         if (glw::GLenum error = gl.getError())
1427                         {
1428                                 m_context.getTestContext().getLog()
1429                                         << tcu::TestLog::Message << "NamedFramebufferReadBuffer unexpectedly generated "
1430                                         << glu::getErrorStr(error) << " error with GL_COLOR_ATTACHMENT" << i << ". Test fails."
1431                                         << tcu::TestLog::EndMessage;
1432                                 is_ok = false;
1433                         }
1434
1435                         glw::GLfloat rgba[4] = { -1.f, -1.f, -1.f, -1.f };
1436
1437                         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, rgba);
1438                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
1439
1440                         float expected_value = (float)i / (float)max_color_attachments;
1441
1442                         for (glw::GLuint j = 0; j < 4 /* number of components */; ++j)
1443                         {
1444                                 if (de::abs(expected_value - rgba[j]) > 0.0001 /* Precision */)
1445                                 {
1446                                         m_context.getTestContext().getLog()
1447                                                 << tcu::TestLog::Message
1448                                                 << "Named Framebuffer Draw And Read Buffer failed because resulting color value was ["
1449                                                 << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << "] but ["
1450                                                 << expected_value << ", " << expected_value << ", " << expected_value << ", " << expected_value
1451                                                 << "] had been expected." << tcu::TestLog::EndMessage;
1452
1453                                         is_ok = false;
1454
1455                                         break;
1456                                 }
1457                         }
1458                 }
1459
1460                 /* Check that NamedFramebufferDrawBuffer accepts GL_NONE as mode. */
1461                 gl.namedFramebufferDrawBuffer(framebuffer, GL_NONE);
1462
1463                 if (glw::GLenum error = gl.getError())
1464                 {
1465                         m_context.getTestContext().getLog()
1466                                 << tcu::TestLog::Message << "NamedFramebufferDrawBuffer unexpectedly generated "
1467                                 << glu::getErrorStr(error) << " error with GL_NONE mode. Test fails." << tcu::TestLog::EndMessage;
1468                         is_ok = false;
1469                 }
1470
1471                 /* Check that NamedFramebufferReadBuffer accepts GL_NONE as mode. */
1472                 gl.namedFramebufferReadBuffer(framebuffer, GL_NONE);
1473
1474                 if (glw::GLenum error = gl.getError())
1475                 {
1476                         m_context.getTestContext().getLog()
1477                                 << tcu::TestLog::Message << "NamedFramebufferReadBuffer unexpectedly generated "
1478                                 << glu::getErrorStr(error) << " error with GL_NONE mode. Test fails." << tcu::TestLog::EndMessage;
1479                         is_ok = false;
1480                 }
1481         }
1482         catch (...)
1483         {
1484                 is_ok   = false;
1485                 is_error = true;
1486         }
1487
1488         /* Cleanup. */
1489         if (framebuffer)
1490         {
1491                 gl.deleteFramebuffers(1, &framebuffer);
1492
1493                 framebuffer = 0;
1494         }
1495
1496         for (glw::GLint i = 0; i < max_color_attachments; ++i)
1497         {
1498                 if (renderbuffers[i])
1499                 {
1500                         gl.deleteRenderbuffers(1, &(renderbuffers[i]));
1501                 }
1502         }
1503
1504         gl.clearColor(0.f, 0.f, 0.f, 0.f);
1505
1506         /* Errors clean up. */
1507         while (gl.getError())
1508                 ;
1509
1510         /* Result's setup. */
1511         if (is_ok)
1512         {
1513                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1514         }
1515         else
1516         {
1517                 if (is_error)
1518                 {
1519                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1520                 }
1521                 else
1522                 {
1523                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1524                 }
1525         }
1526
1527         return STOP;
1528 }
1529
1530 /******************************** Named Framebuffer Draw Buffers Test Implementation   ********************************/
1531
1532 /** @brief Named Framebuffer Draw Buffers Test constructor.
1533  *
1534  *  @param [in] context     OpenGL context.
1535  */
1536 DrawBuffersTest::DrawBuffersTest(deqp::Context& context)
1537         : deqp::TestCase(context, "framebuffers_draw_buffers", "Framebuffer Draw Buffers Test")
1538 {
1539         /* Intentionally left blank. */
1540 }
1541
1542 /** @brief Iterate Named Framebuffer Read / Draw Buffer Test cases.
1543  *
1544  *  @return Iteration result.
1545  */
1546 tcu::TestNode::IterateResult DrawBuffersTest::iterate()
1547 {
1548         /* Shortcut for GL functionality. */
1549         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1550
1551         /* Get context setup. */
1552         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1553         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1554
1555         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1556         {
1557                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1558
1559                 return STOP;
1560         }
1561
1562         /* Running tests. */
1563         bool is_ok      = true;
1564         bool is_error = false;
1565
1566         /* Framebuffers' objects */
1567         glw::GLuint framebuffer = 0;
1568
1569         /* Get number of color attachments. */
1570         glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;
1571
1572         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
1573         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
1574
1575         std::vector<glw::GLuint> renderbuffers(max_color_attachments);
1576         std::vector<glw::GLuint> color_attachments(max_color_attachments);
1577
1578         for (glw::GLint i = 0; i < max_color_attachments; ++i)
1579         {
1580                 renderbuffers[i]         = 0;
1581                 color_attachments[i] = GL_COLOR_ATTACHMENT0 + i;
1582         }
1583
1584         try
1585         {
1586                 /* Prepare framebuffer... */
1587                 gl.genFramebuffers(1, &framebuffer);
1588                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
1589
1590                 gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1591                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
1592
1593                 gl.genRenderbuffers(max_color_attachments, &(renderbuffers[0]));
1594                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
1595
1596                 /* .. with renderbuffer color attachments. */
1597                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
1598                 {
1599                         gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
1600                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
1601
1602                         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
1603                         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
1604
1605                         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, renderbuffers[i]);
1606                         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
1607                 }
1608
1609                 /* Check that framebuffer is complete. */
1610                 if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
1611                 {
1612                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
1613                                                                                                 << tcu::TestLog::EndMessage;
1614
1615                         throw 0;
1616                 }
1617
1618                 /* Set up all attachments as draw buffer. */
1619                 gl.namedFramebufferDrawBuffers(framebuffer, max_color_attachments, &(color_attachments[0]));
1620
1621                 if (glw::GLenum error = gl.getError())
1622                 {
1623                         m_context.getTestContext().getLog()
1624                                 << tcu::TestLog::Message << "NamedFramebufferDrawBuffers unexpectedly generated "
1625                                 << glu::getErrorStr(error) << " error. Test fails." << tcu::TestLog::EndMessage;
1626                         is_ok = false;
1627                 }
1628
1629                 /* Clear each of the framebuffer's attachments with unique color using NamedFramebufferDrawBuffer for attachment selection. */
1630                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
1631                 {
1632                         gl.clearColor(s_rgba[0], s_rgba[1], s_rgba[2], s_rgba[3]);
1633                         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");
1634
1635                         gl.clear(GL_COLOR_BUFFER_BIT);
1636                         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear has failed");
1637                 }
1638
1639                 /* Fetch framebuffer's content and compare it with reference using NamedFramebufferReadBuffer for attachment selection. */
1640                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
1641                 {
1642                         gl.readBuffer(GL_COLOR_ATTACHMENT0 + i);
1643                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer has failed");
1644
1645                         glw::GLfloat rgba[4] = { -1.f, -1.f, -1.f, -1.f };
1646
1647                         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, rgba);
1648                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
1649
1650                         for (glw::GLuint j = 0; j < 4 /* number of components */; ++j)
1651                         {
1652                                 if (de::abs(s_rgba[j] - rgba[j]) > 0.0001 /* Precision */)
1653                                 {
1654                                         m_context.getTestContext().getLog()
1655                                                 << tcu::TestLog::Message
1656                                                 << "Named Framebuffer Draw Buffers test have failed because resulting color value was ["
1657                                                 << rgba[0] << ", " << rgba[1] << ", " << rgba[2] << ", " << rgba[3] << "] but [" << s_rgba[0]
1658                                                 << ", " << s_rgba[1] << ", " << s_rgba[2] << ", " << s_rgba[3] << "] had been expected."
1659                                                 << tcu::TestLog::EndMessage;
1660
1661                                         is_ok = false;
1662
1663                                         break;
1664                                 }
1665                         }
1666                 }
1667
1668                 /* Check that NamedFramebufferDrawBuffers accepts GL_NONE as mode. */
1669                 glw::GLenum none_bufs = GL_NONE;
1670                 gl.namedFramebufferDrawBuffers(framebuffer, 1, &none_bufs);
1671
1672                 if (glw::GLenum error = gl.getError())
1673                 {
1674                         m_context.getTestContext().getLog()
1675                                 << tcu::TestLog::Message << "NamedFramebufferDrawBuffers unexpectedly generated "
1676                                 << glu::getErrorStr(error) << " error with GL_NONE mode. Test fails." << tcu::TestLog::EndMessage;
1677                         is_ok = false;
1678                 }
1679         }
1680         catch (...)
1681         {
1682                 is_ok   = false;
1683                 is_error = true;
1684         }
1685
1686         /* Cleanup. */
1687         if (framebuffer)
1688         {
1689                 gl.deleteFramebuffers(1, &framebuffer);
1690
1691                 framebuffer = 0;
1692         }
1693
1694         for (glw::GLint i = 0; i < max_color_attachments; ++i)
1695         {
1696                 if (renderbuffers[i])
1697                 {
1698                         gl.deleteRenderbuffers(1, &(renderbuffers[i]));
1699                 }
1700         }
1701
1702         gl.clearColor(0.f, 0.f, 0.f, 0.f);
1703
1704         /* Errors clean up. */
1705         while (gl.getError())
1706                 ;
1707
1708         /* Result's setup. */
1709         if (is_ok)
1710         {
1711                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1712         }
1713         else
1714         {
1715                 if (is_error)
1716                 {
1717                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1718                 }
1719                 else
1720                 {
1721                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1722                 }
1723         }
1724
1725         return STOP;
1726 }
1727
1728 const glw::GLfloat DrawBuffersTest::s_rgba[4] = { 0.f, 0.25f, 0.5f, 0.75f };
1729
1730 /******************************** Named Framebuffer Invalidate Data Test Implementation   ********************************/
1731
1732 /** @brief Named Framebuffer Invalidate Data Test constructor.
1733  *
1734  *  @param [in] context     OpenGL context.
1735  */
1736 InvalidateDataTest::InvalidateDataTest(deqp::Context& context)
1737         : deqp::TestCase(context, "framebuffers_invalidate_data", "Framebuffer Invalidate Data Test")
1738 {
1739         /* Intentionally left blank. */
1740 }
1741
1742 /** @brief Iterate Named Framebuffer Read / Draw Buffer Test cases.
1743  *
1744  *  @return Iteration result.
1745  */
1746 tcu::TestNode::IterateResult InvalidateDataTest::iterate()
1747 {
1748         /* Shortcut for GL functionality. */
1749         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1750
1751         /* Get context setup. */
1752         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1753         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1754
1755         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1756         {
1757                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1758
1759                 return STOP;
1760         }
1761
1762         /* Running tests. */
1763         bool is_ok      = true;
1764         bool is_error = false;
1765
1766         /* Framebuffers' objects */
1767         glw::GLuint framebuffer = 0;
1768
1769         /* Get number of color attachments. */
1770         glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;
1771
1772         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
1773         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
1774
1775         std::vector<glw::GLuint> renderbuffers(max_color_attachments);
1776         std::vector<glw::GLuint> color_attachments(max_color_attachments);
1777         static const glw::GLenum default_attachments[]   = { GL_COLOR, GL_DEPTH, GL_STENCIL };
1778         static const glw::GLuint default_attachments_count = sizeof(default_attachments) / sizeof(default_attachments[0]);
1779
1780         for (glw::GLint i = 0; i < max_color_attachments; ++i)
1781         {
1782                 renderbuffers[i]         = 0;
1783                 color_attachments[i] = GL_COLOR_ATTACHMENT0 + i;
1784         }
1785
1786         try
1787         {
1788                 /* Invalidate Default Framebuffer data */
1789                 gl.invalidateNamedFramebufferData(0, default_attachments_count, &(default_attachments[0]));
1790                 is_ok &= CheckErrorAndLog(default_attachments, default_attachments_count);
1791
1792                 for (glw::GLuint i = 0; i < default_attachments_count; ++i)
1793                 {
1794                         gl.invalidateNamedFramebufferData(0, 1, &(default_attachments[i]));
1795                         is_ok &= CheckErrorAndLog(default_attachments[i]);
1796                 }
1797
1798                 /* Prepare framebuffer... */
1799                 gl.genFramebuffers(1, &framebuffer);
1800                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
1801
1802                 gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1803                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
1804
1805                 gl.genRenderbuffers(max_color_attachments, &(renderbuffers[0]));
1806                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
1807
1808                 /* .. with renderbuffer color attachments. */
1809                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
1810                 {
1811                         gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
1812                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
1813
1814                         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 1, 1);
1815                         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
1816
1817                         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, renderbuffers[i]);
1818                         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
1819                 }
1820
1821                 /* Check that framebuffer is complete. */
1822                 if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
1823                 {
1824                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
1825                                                                                                 << tcu::TestLog::EndMessage;
1826
1827                         throw 0;
1828                 }
1829
1830                 gl.invalidateNamedFramebufferData(framebuffer, max_color_attachments, &(color_attachments[0]));
1831                 is_ok &= CheckErrorAndLog(&(color_attachments[0]), max_color_attachments);
1832
1833                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
1834                 {
1835                         gl.invalidateNamedFramebufferData(framebuffer, 1, &(color_attachments[i]));
1836                         is_ok &= CheckErrorAndLog(color_attachments[i]);
1837                 }
1838         }
1839         catch (...)
1840         {
1841                 is_ok   = false;
1842                 is_error = true;
1843         }
1844
1845         /* Cleanup. */
1846         if (framebuffer)
1847         {
1848                 gl.deleteFramebuffers(1, &framebuffer);
1849
1850                 framebuffer = 0;
1851         }
1852
1853         for (glw::GLint i = 0; i < max_color_attachments; ++i)
1854         {
1855                 if (renderbuffers[i])
1856                 {
1857                         gl.deleteRenderbuffers(1, &(renderbuffers[i]));
1858                 }
1859         }
1860
1861         /* Errors clean up. */
1862         while (gl.getError())
1863                 ;
1864
1865         /* Result's setup. */
1866         if (is_ok)
1867         {
1868                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1869         }
1870         else
1871         {
1872                 if (is_error)
1873                 {
1874                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
1875                 }
1876                 else
1877                 {
1878                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1879                 }
1880         }
1881
1882         return STOP;
1883 }
1884
1885 /** @brief Check error and log.
1886  *
1887  *  @param [in] attachment             Framebuffer attachment.
1888  *
1889  *  @return True if no error, false otherwise.
1890  */
1891 bool InvalidateDataTest::CheckErrorAndLog(const glw::GLenum attachment)
1892 {
1893         /* Shortcut for GL functionality. */
1894         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1895
1896         /* Check error. */
1897         if (glw::GLenum error = gl.getError())
1898         {
1899                 /* There is an error. Log. */
1900                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "InvalidateDataTest unexpectedly generated "
1901                                                                                         << glu::getErrorStr(error) << " error for attachment "
1902                                                                                         << glu::getFramebufferAttachmentStr(attachment) << ". Test fails."
1903                                                                                         << tcu::TestLog::EndMessage;
1904
1905                 return false;
1906         }
1907
1908         return true;
1909 }
1910
1911 /** @brief Check error and log.
1912  *
1913  *  @param [in] attachments             Framebuffer attachments.
1914  *  @param [in] attachments_count       Framebuffer attachments count.
1915  *
1916  *  @return True if no error, false otherwise.
1917  */
1918 bool InvalidateDataTest::CheckErrorAndLog(const glw::GLenum attachments[], glw::GLuint count)
1919 {
1920         /* Shortcut for GL functionality. */
1921         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1922
1923         /* Check error. */
1924         if (glw::GLenum error = gl.getError())
1925         {
1926                 /* There is an error. Log. */
1927                 std::string attachments_names = "";
1928
1929                 for (glw::GLuint i = 0; i < count; ++i)
1930                 {
1931                         attachments_names.append(glu::getFramebufferAttachmentStr(attachments[i]).toString());
1932
1933                         if ((count - 1) != i)
1934                         {
1935                                 attachments_names.append(", ");
1936                         }
1937                 }
1938
1939                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "InvalidateDataTest unexpectedly generated "
1940                                                                                         << glu::getErrorStr(error) << " error for following attachments ["
1941                                                                                         << attachments_names << "]. Test fails." << tcu::TestLog::EndMessage;
1942
1943                 return false;
1944         }
1945
1946         return true;
1947 }
1948
1949 /******************************** Named Framebuffer Invalidate Sub Data Test Implementation   ********************************/
1950
1951 /** @brief Named Framebuffer Invalidate Sub Data Test constructor.
1952  *
1953  *  @param [in] context     OpenGL context.
1954  */
1955 InvalidateSubDataTest::InvalidateSubDataTest(deqp::Context& context)
1956         : deqp::TestCase(context, "framebuffers_invalidate_subdata", "Framebuffer Invalidate Sub Data Test")
1957 {
1958         /* Intentionally left blank. */
1959 }
1960
1961 /** @brief Iterate Named Framebuffer Read / Draw Buffer Test cases.
1962  *
1963  *  @return Iteration result.
1964  */
1965 tcu::TestNode::IterateResult InvalidateSubDataTest::iterate()
1966 {
1967         /* Shortcut for GL functionality. */
1968         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1969
1970         /* Get context setup. */
1971         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
1972         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
1973
1974         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
1975         {
1976                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
1977
1978                 return STOP;
1979         }
1980
1981         /* Running tests. */
1982         bool is_ok      = true;
1983         bool is_error = false;
1984
1985         /* Framebuffers' objects */
1986         glw::GLuint framebuffer = 0;
1987
1988         /* Get number of color attachments. */
1989         glw::GLint max_color_attachments = 8 /* Specification minimum OpenGL 4.5 Core Profile p. 627 */;
1990
1991         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
1992         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
1993
1994         std::vector<glw::GLuint> renderbuffers(max_color_attachments);
1995         std::vector<glw::GLuint> color_attachments(max_color_attachments);
1996         static const glw::GLenum default_attachments[]   = { GL_COLOR, GL_DEPTH, GL_STENCIL };
1997         static const glw::GLuint default_attachments_count = sizeof(default_attachments) / sizeof(default_attachments[0]);
1998
1999         for (glw::GLint i = 0; i < max_color_attachments; ++i)
2000         {
2001                 renderbuffers[i]         = 0;
2002                 color_attachments[i] = GL_COLOR_ATTACHMENT0 + i;
2003         }
2004
2005         try
2006         {
2007                 /* Invalidate Default Framebuffer data */
2008                 gl.invalidateNamedFramebufferSubData(0, default_attachments_count, &(default_attachments[0]), 0, 0, 1, 1);
2009                 is_ok &= CheckErrorAndLog(default_attachments, default_attachments_count);
2010
2011                 for (glw::GLuint i = 0; i < default_attachments_count; ++i)
2012                 {
2013                         gl.invalidateNamedFramebufferSubData(0, 1, &(default_attachments[i]), 0, 0, 1, 1);
2014                         is_ok &= CheckErrorAndLog(default_attachments[i]);
2015                 }
2016
2017                 /* Prepare framebuffer... */
2018                 gl.genFramebuffers(1, &framebuffer);
2019                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
2020
2021                 gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2022                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
2023
2024                 gl.genRenderbuffers(max_color_attachments, &(renderbuffers[0]));
2025                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
2026
2027                 /* .. with renderbuffer color attachments. */
2028                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
2029                 {
2030                         gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffers[i]);
2031                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
2032
2033                         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA32F, 4, 4);
2034                         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
2035
2036                         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER, renderbuffers[i]);
2037                         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
2038                 }
2039
2040                 /* Check that framebuffer is complete. */
2041                 if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
2042                 {
2043                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
2044                                                                                                 << tcu::TestLog::EndMessage;
2045
2046                         throw 0;
2047                 }
2048
2049                 gl.invalidateNamedFramebufferSubData(framebuffer, max_color_attachments, &(color_attachments[0]), 1, 1, 2, 2);
2050                 is_ok &= CheckErrorAndLog(&(color_attachments[0]), max_color_attachments);
2051
2052                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
2053                 {
2054                         gl.invalidateNamedFramebufferSubData(framebuffer, 1, &(color_attachments[i]), 1, 1, 2, 2);
2055                         is_ok &= CheckErrorAndLog(color_attachments[i]);
2056                 }
2057         }
2058         catch (...)
2059         {
2060                 is_ok   = false;
2061                 is_error = true;
2062         }
2063
2064         /* Cleanup. */
2065         if (framebuffer)
2066         {
2067                 gl.deleteFramebuffers(1, &framebuffer);
2068
2069                 framebuffer = 0;
2070         }
2071
2072         for (glw::GLint i = 0; i < max_color_attachments; ++i)
2073         {
2074                 if (renderbuffers[i])
2075                 {
2076                         gl.deleteRenderbuffers(1, &(renderbuffers[i]));
2077                 }
2078         }
2079
2080         /* Errors clean up. */
2081         while (gl.getError())
2082                 ;
2083
2084         /* Result's setup. */
2085         if (is_ok)
2086         {
2087                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2088         }
2089         else
2090         {
2091                 if (is_error)
2092                 {
2093                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2094                 }
2095                 else
2096                 {
2097                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2098                 }
2099         }
2100
2101         return STOP;
2102 }
2103
2104 /** @brief Check error and log.
2105  *
2106  *  @param [in] attachment             Framebuffer attachment.
2107  *
2108  *  @return True if no error, false otherwise.
2109  */
2110 bool InvalidateSubDataTest::CheckErrorAndLog(const glw::GLenum attachment)
2111 {
2112         /* Shortcut for GL functionality. */
2113         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2114
2115         /* Check error. */
2116         if (glw::GLenum error = gl.getError())
2117         {
2118                 /* There is an error. Log. */
2119                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "InvalidateSubDataTest unexpectedly generated "
2120                                                                                         << glu::getErrorStr(error) << " error for attachment "
2121                                                                                         << glu::getFramebufferAttachmentStr(attachment) << ". Test fails."
2122                                                                                         << tcu::TestLog::EndMessage;
2123
2124                 return false;
2125         }
2126
2127         return true;
2128 }
2129
2130 /** @brief Check error and log.
2131  *
2132  *  @param [in] attachments             Framebuffer attachments.
2133  *  @param [in] attachments_count       Framebuffer attachments count.
2134  *
2135  *  @return True if no error, false otherwise.
2136  */
2137 bool InvalidateSubDataTest::CheckErrorAndLog(const glw::GLenum attachments[], glw::GLuint count)
2138 {
2139         /* Shortcut for GL functionality. */
2140         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2141
2142         /* Check error. */
2143         if (glw::GLenum error = gl.getError())
2144         {
2145                 /* There is an error. Log. */
2146                 std::string attachments_names = "";
2147
2148                 for (glw::GLuint i = 0; i < count; ++i)
2149                 {
2150                         attachments_names.append(glu::getFramebufferAttachmentStr(attachments[i]).toString());
2151
2152                         if ((count - 1) != i)
2153                         {
2154                                 attachments_names.append(", ");
2155                         }
2156                 }
2157
2158                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "InvalidateSubDataTest unexpectedly generated "
2159                                                                                         << glu::getErrorStr(error) << " error for following attachments ["
2160                                                                                         << attachments_names << "]. Test fails." << tcu::TestLog::EndMessage;
2161
2162                 return false;
2163         }
2164
2165         return true;
2166 }
2167
2168 /******************************** Clear Named Framebuffer Test Implementation   ********************************/
2169
2170 /** @brief Clear Named Framebuffer Test constructor.
2171  *
2172  *  @param [in] context     OpenGL context.
2173  */
2174 ClearTest::ClearTest(deqp::Context& context)
2175         : deqp::TestCase(context, "framebuffers_clear", "Clear Named Framebuffer Test")
2176         , m_fbo(0)
2177         , m_renderbuffers(0)
2178         , m_renderbuffers_count(0)
2179 {
2180         /* Intentionally left blank. */
2181 }
2182
2183 /** @brief Compare two floats (template specialization).
2184  *
2185  *  @param [in] first        First  float to be compared.
2186  *  @param [in] second       Second float to be compared.
2187  *
2188  *  @return True if floats are equal within +-(1.f/64.f) precision range, false otherwise.
2189  */
2190 template <>
2191 bool ClearTest::Compare<glw::GLfloat>(const glw::GLfloat first, const glw::GLfloat second)
2192 {
2193         return (de::abs(first - second) < (1.f / 64.f) /* Precission. */);
2194 }
2195
2196 /** @brief Compare two objects (template general specialization).
2197  *
2198  *  @param [in] first        First  objetc to be compared.
2199  *  @param [in] second       Second object to be compared.
2200  *
2201  *  @return True if floats are equal, false otherwise.
2202  */
2203 template <typename T>
2204 bool ClearTest::Compare(const T first, const T second)
2205 {
2206         return (first == second);
2207 }
2208
2209 /** @brief Clear color buffer (float specialization), check errors and log.
2210  *
2211  *  @param [in] buffer      Buffer to be cleared.
2212  *  @param [in] drawbuffer  Drawbuffer to be cleared.
2213  *  @param [in] value       Value to be cleared with.
2214  *
2215  *  @return True if succeeded without errors, false otherwise.
2216  */
2217 template <>
2218 bool ClearTest::ClearColor<glw::GLfloat>(glw::GLenum buffer, glw::GLint drawbuffer, glw::GLfloat value)
2219 {
2220         /* Shortcut for GL functionality. */
2221         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2222
2223         glw::GLfloat value_vector[4] = { value, 0, 0, 0 };
2224
2225         gl.clearNamedFramebufferfv(m_fbo, buffer, drawbuffer, value_vector);
2226
2227         if (glw::GLenum error = gl.getError())
2228         {
2229                 m_context.getTestContext().getLog()
2230                         << tcu::TestLog::Message << "ClearNamedFramebufferfv unexpectedly generated " << glu::getErrorStr(error)
2231                         << " error. Test fails." << tcu::TestLog::EndMessage;
2232
2233                 return false;
2234         }
2235
2236         return true;
2237 }
2238
2239 /** @brief Clear color buffer (int specialization), check errors and log.
2240  *
2241  *  @param [in] buffer      Buffer to be cleared.
2242  *  @param [in] drawbuffer  Drawbuffer to be cleared.
2243  *  @param [in] value       Value to be cleared with.
2244  *
2245  *  @return True if succeeded without errors, false otherwise.
2246  */
2247 template <>
2248 bool ClearTest::ClearColor<glw::GLint>(glw::GLenum buffer, glw::GLint drawbuffer, glw::GLint value)
2249 {
2250         /* Shortcut for GL functionality. */
2251         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2252
2253         glw::GLint value_vector[4] = { value, 0, 0, 0 };
2254
2255         gl.clearNamedFramebufferiv(m_fbo, buffer, drawbuffer, value_vector);
2256
2257         if (glw::GLenum error = gl.getError())
2258         {
2259                 m_context.getTestContext().getLog()
2260                         << tcu::TestLog::Message << "ClearNamedFramebufferiv unexpectedly generated " << glu::getErrorStr(error)
2261                         << " error. Test fails." << tcu::TestLog::EndMessage;
2262
2263                 return false;
2264         }
2265
2266         return true;
2267 }
2268
2269 /** @brief Clear color buffer (uint specialization), check errors and log.
2270  *
2271  *  @param [in] buffer      Buffer to be cleared.
2272  *  @param [in] drawbuffer  Drawbuffer to be cleared.
2273  *  @param [in] value       Value to be cleared with.
2274  *
2275  *  @return True if succeeded without errors, false otherwise.
2276  */
2277 template <>
2278 bool ClearTest::ClearColor<glw::GLuint>(glw::GLenum buffer, glw::GLint drawbuffer, glw::GLuint value)
2279 {
2280         /* Shortcut for GL functionality. */
2281         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2282
2283         glw::GLuint value_vector[4] = { value, 0, 0, 0 };
2284
2285         gl.clearNamedFramebufferuiv(m_fbo, buffer, drawbuffer, value_vector);
2286
2287         if (glw::GLenum error = gl.getError())
2288         {
2289                 m_context.getTestContext().getLog()
2290                         << tcu::TestLog::Message << "ClearNamedFramebufferuiv unexpectedly generated " << glu::getErrorStr(error)
2291                         << " error. Test fails." << tcu::TestLog::EndMessage;
2292
2293                 return false;
2294         }
2295
2296         return true;
2297 }
2298
2299 /** @brief Format of the buffer (float specialization).
2300  *
2301  *  @return Format.
2302  */
2303 template <>
2304 glw::GLenum ClearTest::Format<GLfloat>()
2305 {
2306         return GL_RED;
2307 }
2308
2309 /** @brief Format of the buffer (int and uint specialization).
2310  *
2311  *  @return Format.
2312  */
2313 template <typename T>
2314 glw::GLenum ClearTest::Format()
2315 {
2316         return GL_RED_INTEGER;
2317 }
2318
2319 /** @brief Type of the buffer (float specialization).
2320  *
2321  *  @return Type.
2322  */
2323 template <>
2324 glw::GLenum ClearTest::Type<glw::GLfloat>()
2325 {
2326         return GL_FLOAT;
2327 }
2328
2329 /** @brief Type of the buffer (int specialization).
2330  *
2331  *  @return Type.
2332  */
2333 template <>
2334 glw::GLenum ClearTest::Type<glw::GLint>()
2335 {
2336         return GL_INT;
2337 }
2338
2339 /** @brief Type of the buffer (uint specialization).
2340  *
2341  *  @return Type.
2342  */
2343 template <>
2344 glw::GLenum ClearTest::Type<glw::GLuint>()
2345 {
2346         return GL_UNSIGNED_INT;
2347 }
2348
2349 /** @brief Test DSA Clear function (color).
2350  *
2351  *  @param [in] buffer      Buffer to be cleared.
2352  *  @param [in] attachment  Attachment to be tested.
2353  *  @param [in] value       Value to be cleared with.
2354  *
2355  *  @return True if test succeeded, false otherwise.
2356  */
2357 template <typename T>
2358 bool ClearTest::TestClearColor(glw::GLenum buffer, glw::GLenum attachment, T value)
2359 {
2360         /* Shortcut for GL functionality. */
2361         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2362
2363         gl.drawBuffer(attachment);
2364         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer has failed");
2365
2366         /* Clear. */
2367         if (ClearColor<T>(buffer, 0, value))
2368         {
2369                 /* Fetching framebuffer content. */
2370                 T pixel = (T)0;
2371
2372                 gl.readBuffer(attachment);
2373                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer has failed");
2374
2375                 gl.readPixels(0, 0, 1, 1, Format<T>(), Type<T>(), &pixel);
2376                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixel has failed");
2377
2378                 /* Comparison with reference value. */
2379                 if (Compare(pixel, value))
2380                 {
2381                         return true;
2382                 }
2383
2384                 m_context.getTestContext().getLog()
2385                         << tcu::TestLog::Message << "ClearNamedFramebuffer did not cleared color attachment "
2386                         << glu::getFramebufferAttachmentStr(attachment) << " of the framebuffer." << tcu::TestLog::EndMessage;
2387         }
2388
2389         return false;
2390 }
2391
2392 /** @brief Test DSA Clear function (depth/stencil).
2393  *
2394  *  @param [in] stencil     Stencil value to be cleared with.
2395  *  @param [in] depth       Depth value to be cleared with.
2396  *
2397  *  @return True if test succeeded, false otherwise.
2398  */
2399 bool ClearTest::TestClearDepthAndStencil(glw::GLfloat depth, glw::GLint stencil)
2400 {
2401         /* Shortcut for GL functionality. */
2402         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2403
2404         /* Clearing depth and stencil. */
2405         gl.clearNamedFramebufferfi(m_fbo, GL_DEPTH_STENCIL, 0, depth, stencil);
2406
2407         if (glw::GLenum error = gl.getError())
2408         {
2409                 m_context.getTestContext().getLog()
2410                         << tcu::TestLog::Message << "ClearNamedFramebufferufi unexpectedly generated " << glu::getErrorStr(error)
2411                         << " error. Test fails." << tcu::TestLog::EndMessage;
2412
2413                 return false;
2414         }
2415
2416         /* Clear. */
2417         /* Fetching framebuffer content. */
2418         glw::GLfloat the_depth   = 0.f;
2419         glw::GLint   the_stencil = 0;
2420
2421         gl.readPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &the_depth);
2422         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixel has failed");
2423
2424         gl.readPixels(0, 0, 1, 1, GL_STENCIL_INDEX, GL_INT, &the_stencil);
2425         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixel has failed");
2426
2427         /* Comparison with reference value. */
2428         if (Compare(the_depth, depth) || Compare(the_stencil, stencil))
2429         {
2430                 return true;
2431         }
2432
2433         m_context.getTestContext().getLog()
2434                 << tcu::TestLog::Message
2435                 << "ClearNamedFramebufferfi did not cleared depth/stencil attachment of the framebuffer."
2436                 << tcu::TestLog::EndMessage;
2437
2438         return true;
2439 }
2440
2441 /** @brief Iterate Clear Named Framebuffer Test cases.
2442  *
2443  *  @return Iteration result.
2444  */
2445 tcu::TestNode::IterateResult ClearTest::iterate()
2446 {
2447         /* Get context setup. */
2448         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2449         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2450
2451         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2452         {
2453                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2454
2455                 return STOP;
2456         }
2457
2458         /* Running tests. */
2459         bool is_ok      = true;
2460         bool is_error = false;
2461
2462         try
2463         {
2464                 /* Fixed point color test. */
2465                 PrepareFramebuffer(GL_COLOR, GL_R8);
2466
2467                 for (glw::GLint i = 0; i < (glw::GLint)m_renderbuffers_count; ++i)
2468                 {
2469                         is_ok &= TestClearColor<glw::GLfloat>(GL_COLOR, GL_COLOR_ATTACHMENT0 + i, 0.5);
2470                 }
2471
2472                 Clean();
2473
2474                 /* Floating point color test. */
2475                 PrepareFramebuffer(GL_COLOR, GL_R32F);
2476
2477                 for (glw::GLint i = 0; i < (glw::GLint)m_renderbuffers_count; ++i)
2478                 {
2479                         is_ok &= TestClearColor<glw::GLfloat>(GL_COLOR, GL_COLOR_ATTACHMENT0 + i, 0.5);
2480                 }
2481
2482                 Clean();
2483
2484                 /* Signed integer color test. */
2485                 PrepareFramebuffer(GL_COLOR, GL_R8I);
2486
2487                 for (glw::GLint i = 0; i < (glw::GLint)m_renderbuffers_count; ++i)
2488                 {
2489                         is_ok &= TestClearColor<glw::GLint>(GL_COLOR, GL_COLOR_ATTACHMENT0 + i, -16);
2490                 }
2491
2492                 Clean();
2493
2494                 /* Unsigned integer color test. */
2495                 PrepareFramebuffer(GL_COLOR, GL_R8UI);
2496
2497                 for (glw::GLint i = 0; i < (glw::GLint)m_renderbuffers_count; ++i)
2498                 {
2499                         is_ok &= TestClearColor<glw::GLuint>(GL_COLOR, GL_COLOR_ATTACHMENT0 + i, 16);
2500                 }
2501
2502                 Clean();
2503
2504                 /* Depth / stencil test. */
2505                 PrepareFramebuffer(GL_DEPTH_STENCIL, GL_DEPTH24_STENCIL8);
2506
2507                 is_ok &= TestClearDepthAndStencil(1, 1);
2508
2509                 Clean();
2510         }
2511         catch (...)
2512         {
2513                 is_ok   = false;
2514                 is_error = true;
2515         }
2516
2517         /* Cleanup. */
2518         Clean();
2519
2520         /* Result's setup. */
2521         if (is_ok)
2522         {
2523                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2524         }
2525         else
2526         {
2527                 if (is_error)
2528                 {
2529                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2530                 }
2531                 else
2532                 {
2533                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2534                 }
2535         }
2536
2537         return STOP;
2538 }
2539
2540 /** @brief Prepare framebuffer.
2541  *
2542  *  @param [in] buffer          Buffer to be prepared.
2543  *  @param [in] internalformat  Internal format to be prepared
2544  */
2545 void ClearTest::PrepareFramebuffer(glw::GLenum buffer, glw::GLenum internalformat)
2546 {
2547         /* Shortcut for GL functionality. */
2548         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2549
2550         /* Check that ther is no other fbo. */
2551         if ((0 != m_fbo) || (DE_NULL != m_renderbuffers))
2552         {
2553                 throw 0;
2554         }
2555
2556         /* Prepare framebuffer... */
2557         gl.genFramebuffers(1, &m_fbo);
2558         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
2559
2560         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
2561         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
2562
2563         if (buffer == GL_COLOR)
2564         {
2565                 glw::GLint max_color_attachments =
2566                         8; /* OpenGL 4.5 specification default (see Implementation Dependent Values tables). */
2567
2568                 gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
2569                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
2570
2571                 m_renderbuffers = new glw::GLuint[max_color_attachments];
2572
2573                 if (m_renderbuffers)
2574                 {
2575                         /* ... with renderbuffer color attachments. */
2576
2577                         gl.genRenderbuffers(max_color_attachments, m_renderbuffers);
2578                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
2579
2580                         m_renderbuffers_count = max_color_attachments;
2581
2582                         for (glw::GLint i = 0; i < max_color_attachments; ++i)
2583                         {
2584                                 gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers[i]);
2585                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
2586
2587                                 gl.renderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
2588                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
2589
2590                                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_RENDERBUFFER,
2591                                                                                    m_renderbuffers[i]);
2592                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
2593                         }
2594                 }
2595         }
2596
2597         if (buffer == GL_DEPTH_STENCIL)
2598         {
2599                 /* ... with depth and stencil attachments. */
2600
2601                 m_renderbuffers = new glw::GLuint[1];
2602
2603                 if (m_renderbuffers)
2604                 {
2605                         gl.genRenderbuffers(1, m_renderbuffers);
2606                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
2607
2608                         gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffers[0]);
2609                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
2610
2611                         m_renderbuffers_count = 1;
2612
2613                         gl.renderbufferStorage(GL_RENDERBUFFER, internalformat, 1, 1);
2614                         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
2615
2616                         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2617                                                                            m_renderbuffers[0]);
2618                         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
2619                 }
2620         }
2621
2622         /* Check that framebuffer is complete. */
2623         if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
2624         {
2625                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
2626                                                                                         << tcu::TestLog::EndMessage;
2627
2628                 throw 0;
2629         }
2630 }
2631
2632 /** @brief Clean up GL state.
2633  */
2634 void ClearTest::Clean()
2635 {
2636         /* Shortcut for GL functionality. */
2637         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2638
2639         /* Releasing objects. */
2640         if (m_fbo)
2641         {
2642                 gl.deleteFramebuffers(1, &m_fbo);
2643
2644                 m_fbo = 0;
2645         }
2646
2647         if (DE_NULL != m_renderbuffers)
2648         {
2649                 if (m_renderbuffers_count)
2650                 {
2651                         gl.deleteRenderbuffers(m_renderbuffers_count, m_renderbuffers);
2652                 }
2653
2654                 delete[] m_renderbuffers;
2655
2656                 m_renderbuffers           = DE_NULL;
2657                 m_renderbuffers_count = 0;
2658         }
2659
2660         /* Errors clean up. */
2661         while (gl.getError())
2662                 ;
2663 }
2664
2665 /******************************** Blit Named Framebuffer Test Implementation   ********************************/
2666
2667 /** @brief Named Framebuffer blit Test constructor.
2668  *
2669  *  @param [in] context     OpenGL context.
2670  */
2671 BlitTest::BlitTest(deqp::Context& context)
2672         : deqp::TestCase(context, "framebuffers_blit", "Framebuffer Blit Test")
2673         , m_fbo_src(0)
2674         , m_rbo_color_src(0)
2675         , m_rbo_depth_stencil_src(0)
2676         , m_fbo_dst(0)
2677         , m_rbo_color_dst(0)
2678         , m_rbo_depth_stencil_dst(0)
2679 {
2680         /* Intentionally left blank. */
2681 }
2682
2683 /** @brief Iterate Named Framebuffer Blit Test cases.
2684  *
2685  *  @return Iteration result.
2686  */
2687 tcu::TestNode::IterateResult BlitTest::iterate()
2688 {
2689         /* Shortcut for GL functionality. */
2690         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2691
2692         /* Get context setup. */
2693         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
2694         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
2695
2696         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
2697         {
2698                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
2699
2700                 return STOP;
2701         }
2702
2703         /* Running tests. */
2704         bool is_ok      = true;
2705         bool is_error = false;
2706
2707         try
2708         {
2709                 PrepareFramebuffers();
2710
2711                 is_ok = Test();
2712         }
2713         catch (...)
2714         {
2715                 is_ok   = false;
2716                 is_error = true;
2717         }
2718
2719         /* Cleanup. */
2720         Clean();
2721
2722         /* Errors clean up. */
2723         while (gl.getError())
2724                 ;
2725
2726         /* Result's setup. */
2727         if (is_ok)
2728         {
2729                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2730         }
2731         else
2732         {
2733                 if (is_error)
2734                 {
2735                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
2736                 }
2737                 else
2738                 {
2739                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2740                 }
2741         }
2742
2743         return STOP;
2744 }
2745
2746 /** @brief Prepare framebuffer.
2747  */
2748 void BlitTest::PrepareFramebuffers()
2749 {
2750         /* Shortcut for GL functionality. */
2751         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2752
2753         /* Prepare source framebuffer */
2754         gl.genFramebuffers(1, &m_fbo_src);
2755         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
2756
2757         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_src);
2758         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
2759
2760         gl.genRenderbuffers(1, &m_rbo_color_src);
2761         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
2762
2763         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_color_src);
2764         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
2765
2766         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 2, 2);
2767         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
2768
2769         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color_src);
2770         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
2771
2772         gl.genRenderbuffers(1, &m_rbo_depth_stencil_src);
2773         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
2774
2775         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_depth_stencil_src);
2776         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
2777
2778         gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 2, 2);
2779         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
2780
2781         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil_src);
2782         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
2783
2784         /* Check that framebuffer is complete. */
2785         if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
2786         {
2787                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
2788                                                                                         << tcu::TestLog::EndMessage;
2789
2790                 throw 0;
2791         }
2792
2793         /* Prepare destination framebuffer */
2794         gl.genFramebuffers(1, &m_fbo_dst);
2795         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
2796
2797         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_dst);
2798         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
2799
2800         gl.genRenderbuffers(1, &m_rbo_color_dst);
2801         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
2802
2803         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_color_dst);
2804         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
2805
2806         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 3, 2);
2807         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
2808
2809         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color_dst);
2810         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
2811
2812         gl.genRenderbuffers(1, &m_rbo_depth_stencil_dst);
2813         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
2814
2815         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_depth_stencil_dst);
2816         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
2817
2818         gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 3, 2);
2819         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
2820
2821         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil_dst);
2822         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
2823
2824         /* Check that framebuffer is complete. */
2825         if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
2826         {
2827                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Framebuffer is unexpectedly incomplete."
2828                                                                                         << tcu::TestLog::EndMessage;
2829
2830                 throw 0;
2831         }
2832 }
2833
2834 /** @brief Do the blit test.
2835  */
2836 bool BlitTest::Test()
2837 {
2838         /* Shortcut for GL functionality. */
2839         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2840
2841         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_src);
2842         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
2843
2844         ClearFramebuffer(1.f, 0.f, 0.f, 0.5f, 1);
2845
2846         gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 1, 1, 0, 0, 1, 1,
2847                                                         GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2848
2849         if (CheckErrorAndLog())
2850         {
2851                 ClearFramebuffer(0.f, 1.f, 0.f, 0.25f, 2);
2852
2853                 gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 1, 1, 1, 0, 2, 1, GL_COLOR_BUFFER_BIT, GL_LINEAR);
2854                 gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 1, 1, 1, 0, 2, 1,
2855                                                                 GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2856
2857                 if (CheckErrorAndLog())
2858                 {
2859                         ClearFramebuffer(0.f, 0.f, 1.f, 0.125f, 3);
2860
2861                         gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 2, 2, 2, 0, 3, 1,
2862                                                                         GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2863
2864                         if (CheckErrorAndLog())
2865                         {
2866                                 ClearFramebuffer(1.f, 1.f, 0.f, 0.0625f, 4);
2867
2868                                 gl.blitNamedFramebuffer(m_fbo_src, m_fbo_dst, 0, 0, 1, 1, 0, 1, 3, 2,
2869                                                                                 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2870
2871                                 if (CheckErrorAndLog())
2872                                 {
2873                                         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_dst);
2874                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
2875
2876                                         if (CheckColor() && CheckDepth() && CheckStencil())
2877                                         {
2878                                                 return true;
2879                                         }
2880                                 }
2881                         }
2882                 }
2883         }
2884
2885         return false;
2886 }
2887
2888 /** @brief Check error and log.
2889  *
2890  *  @return true if no error, false otherwise.
2891  */
2892 bool BlitTest::CheckErrorAndLog()
2893 {
2894         /* Shortcut for GL functionality. */
2895         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2896
2897         /* Error query. */
2898         if (glw::GLenum error = gl.getError())
2899         {
2900                 /* Log. */
2901                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "BlitNamedFramebuffer unexpectedly generated "
2902                                                                                         << glu::getErrorStr(error) << " error." << tcu::TestLog::EndMessage;
2903
2904                 /* Returning result. */
2905                 return false;
2906         }
2907
2908         /* Returning result. */
2909         return true;
2910 }
2911
2912 /** @brief Check color and log.
2913  *
2914  *  @return true if color matches reference, false otherwise.
2915  */
2916 bool BlitTest::CheckColor()
2917 {
2918         /* Shortcut for GL functionality. */
2919         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2920
2921         /* Reference values. */
2922         static const glw::GLfloat reference[2][3][4] = {
2923                 { { 1.f, 0.f, 0.f, 1.f }, { 0.f, 1.f, 0.f, 1.f }, { 0.f, 0.f, 1.f, 1.f } },
2924                 { { 1.f, 1.f, 0.f, 1.f }, { 1.f, 1.f, 0.f, 1.f }, { 1.f, 1.f, 0.f, 1.f } }
2925         };
2926
2927         /* Copy buffer. */
2928         glw::GLfloat color[2][3][4] = { { { 0 } } };
2929
2930         /* Reading from GL. */
2931         gl.readPixels(0, 0, 3, 2, GL_RGBA, GL_FLOAT, color);
2932         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
2933
2934         /* Comparison against the reference. */
2935         for (glw::GLuint j = 0; j < 2; ++j)
2936         {
2937                 for (glw::GLuint i = 0; i < 3; ++i)
2938                 {
2939                         for (glw::GLuint k = 0; k < 4; ++k)
2940                         {
2941                                 if (de::abs(reference[j][i][k] - color[j][i][k]) > (1.f / 64.f) /* Precision. */)
2942                                 {
2943                                         /* Log. */
2944                                         m_context.getTestContext().getLog()
2945                                                 << tcu::TestLog::Message << "Blitted framebuffer color buffer contains [[" << color[0][0][0]
2946                                                 << ", " << color[0][0][1] << ", " << color[0][0][2] << ", " << color[0][0][3] << "], ["
2947                                                 << color[0][1][0] << ", " << color[0][1][1] << ", " << color[0][1][2] << ", " << color[0][1][3]
2948                                                 << "], [" << color[0][2][0] << ", " << color[0][2][1] << ", " << color[0][2][2] << ", "
2949                                                 << color[0][2][3] << "],\n[" << color[1][0][0] << ", " << color[1][0][1] << ", "
2950                                                 << color[1][0][2] << ", " << color[1][0][3] << "], [" << color[1][1][0] << ", "
2951                                                 << color[1][1][1] << ", " << color[1][1][2] << ", " << color[1][1][3] << "], ["
2952                                                 << color[1][2][0] << ", " << color[1][2][1] << ", " << color[1][2][2] << ", " << color[1][2][3]
2953                                                 << "]], but\n"
2954                                                 << reference[0][0][0] << ", " << reference[0][0][1] << ", " << reference[0][0][2] << ", "
2955                                                 << reference[0][0][3] << "], [" << reference[0][1][0] << ", " << reference[0][1][1] << ", "
2956                                                 << reference[0][1][2] << ", " << reference[0][1][3] << "], [" << reference[0][2][0] << ", "
2957                                                 << reference[0][2][1] << ", " << reference[0][2][2] << ", " << reference[0][2][3] << "],\n["
2958                                                 << reference[1][0][0] << ", " << reference[1][0][1] << ", " << reference[1][0][2] << ", "
2959                                                 << reference[1][0][3] << "], [" << reference[1][1][0] << ", " << reference[1][1][1] << ", "
2960                                                 << reference[1][1][2] << ", " << reference[1][1][3] << "], [" << reference[1][2][0] << ", "
2961                                                 << reference[1][2][1] << ", " << reference[1][2][2] << ", " << reference[1][2][3]
2962                                                 << "]] was expected.\n"
2963                                                 << tcu::TestLog::EndMessage;
2964
2965                                         return false;
2966                                 }
2967                         }
2968                 }
2969         }
2970
2971         return true;
2972 }
2973
2974 /** @brief Check depth and log.
2975  *
2976  *  @return true if depth matches reference, false otherwise.
2977  */
2978 bool BlitTest::CheckDepth()
2979 {
2980         /* Shortcut for GL functionality. */
2981         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2982
2983         /* Reference values. */
2984         static const glw::GLfloat reference[2][3] = { { 0.5, 0.25, 0.125 }, { 0.0625, 0.0625, 0.0625 } };
2985
2986         /* Copy buffer. */
2987         glw::GLfloat depth[2][3] = { { 0 } };
2988
2989         /* Reading from GL. */
2990         gl.readPixels(0, 0, 3, 2, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
2991         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
2992
2993         /* Comparison against the reference. */
2994         for (glw::GLuint j = 0; j < 2; ++j)
2995         {
2996                 for (glw::GLuint i = 0; i < 3; ++i)
2997                 {
2998                         if (de::abs(reference[j][i] - depth[j][i]) > (1.f / 64.f) /* Precision. */)
2999                         {
3000                                 /* Log. */
3001                                 m_context.getTestContext().getLog()
3002                                         << tcu::TestLog::Message << "Blitted framebuffer depth buffer contains [" << depth[0][0] << ", "
3003                                         << depth[0][1] << ", " << depth[0][2] << ", \n"
3004                                         << depth[1][0] << ", " << depth[1][1] << ", " << depth[1][2] << "], but " << reference[0][0] << ", "
3005                                         << reference[0][1] << ", " << reference[0][2] << ", \n"
3006                                         << reference[1][0] << ", " << reference[1][1] << ", " << reference[1][2] << "] was expected."
3007                                         << tcu::TestLog::EndMessage;
3008
3009                                 return false;
3010                         }
3011                 }
3012         }
3013
3014         return true;
3015 }
3016
3017 /** @brief Check stencil and log.
3018  *
3019  *  @return true if stencil matches reference, false otherwise.
3020  */
3021 bool BlitTest::CheckStencil()
3022 {
3023         /* Shortcut for GL functionality. */
3024         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3025
3026         /* Reference values. */
3027         static const glw::GLint reference[2][3] = { { 1, 2, 3 }, { 4, 4, 4 } };
3028
3029         /* Copy buffer. */
3030         glw::GLint stencil[2][3] = { { 0 } };
3031
3032         /* Reading from GL. */
3033         gl.readPixels(0, 0, 3, 2, GL_STENCIL_INDEX, GL_INT, stencil);
3034         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels has failed");
3035
3036         /* Comparison against the reference. */
3037         for (glw::GLuint j = 0; j < 2; ++j)
3038         {
3039                 for (glw::GLuint i = 0; i < 3; ++i)
3040                 {
3041                         if (reference[j][i] != stencil[j][i])
3042                         {
3043                                 /* Log. */
3044                                 m_context.getTestContext().getLog()
3045                                         << tcu::TestLog::Message << "Blitted framebuffer stencil buffer contains [" << stencil[0][0] << ", "
3046                                         << stencil[0][1] << ", " << stencil[0][2] << ", \n"
3047                                         << stencil[1][0] << ", " << stencil[1][1] << ", " << stencil[1][2] << "], but " << reference[0][0]
3048                                         << ", " << reference[0][1] << ", " << reference[0][2] << ", \n"
3049                                         << reference[1][0] << ", " << reference[1][1] << ", " << reference[1][2] << "] was expected."
3050                                         << tcu::TestLog::EndMessage;
3051
3052                                 return false;
3053                         }
3054                 }
3055         }
3056
3057         return true;
3058 }
3059
3060 /** @brief Clear framebuffer.
3061  *
3062  *  @param [in] red         Color component.
3063  *  @param [in] green       Color component.
3064  *  @param [in] blue        Color component.
3065  *  @param [in] alpha       Color component.
3066  *  @param [in] depth       Depth component.
3067  *  @param [in] stencil     Stencil index.
3068  */
3069 void BlitTest::ClearFramebuffer(glw::GLfloat red, glw::GLfloat green, glw::GLfloat blue, glw::GLfloat depth,
3070                                                                 glw::GLint stencil)
3071 {
3072         /* Shortcut for GL functionality. */
3073         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3074
3075         /* Setup clear values. */
3076         gl.clearColor(red, green, blue, 1.f);
3077         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");
3078
3079         gl.clearDepth(depth);
3080         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");
3081
3082         gl.clearStencil(stencil);
3083         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");
3084
3085         /* Clearing. */
3086         gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3087         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor has failed");
3088 }
3089
3090 /** @brief Clean up GL state.
3091  */
3092 void BlitTest::Clean()
3093 {
3094         /* Shortcut for GL functionality. */
3095         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3096
3097         /* Releasing objects. */
3098         if (m_fbo_src)
3099         {
3100                 gl.deleteFramebuffers(1, &m_fbo_src);
3101
3102                 m_fbo_src = 0;
3103         }
3104
3105         if (m_fbo_dst)
3106         {
3107                 gl.deleteFramebuffers(1, &m_fbo_dst);
3108
3109                 m_fbo_dst = 0;
3110         }
3111
3112         if (m_rbo_color_src)
3113         {
3114                 gl.deleteRenderbuffers(1, &m_rbo_color_src);
3115
3116                 m_rbo_color_src = 0;
3117         }
3118
3119         if (m_rbo_color_dst)
3120         {
3121                 gl.deleteRenderbuffers(1, &m_rbo_color_dst);
3122
3123                 m_rbo_color_dst = 0;
3124         }
3125
3126         if (m_rbo_depth_stencil_src)
3127         {
3128                 gl.deleteRenderbuffers(1, &m_rbo_depth_stencil_src);
3129
3130                 m_rbo_depth_stencil_src = 0;
3131         }
3132
3133         if (m_rbo_depth_stencil_dst)
3134         {
3135                 gl.deleteRenderbuffers(1, &m_rbo_depth_stencil_dst);
3136
3137                 m_rbo_depth_stencil_dst = 0;
3138         }
3139
3140         /* Errors clean up. */
3141         while (gl.getError())
3142                 ;
3143 }
3144
3145 /******************************** Framebuffer Check Status Test Implementation   ********************************/
3146
3147 /** @brief Check Status Test constructor.
3148  *
3149  *  @param [in] context     OpenGL context.
3150  */
3151 CheckStatusTest::CheckStatusTest(deqp::Context& context)
3152         : deqp::TestCase(context, "framebuffers_check_status", "Framebuffer Check Status Test")
3153 {
3154         /* Intentionally left blank. */
3155 }
3156
3157 /** @brief Iterate Check Status Test cases.
3158  *
3159  *  @return Iteration result.
3160  */
3161 tcu::TestNode::IterateResult CheckStatusTest::iterate()
3162 {
3163         /* Shortcut for GL functionality. */
3164         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3165
3166         /* Get context setup. */
3167         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
3168         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
3169
3170         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
3171         {
3172                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
3173
3174                 return STOP;
3175         }
3176
3177         /* Running tests. */
3178         bool is_ok      = true;
3179         bool maybe_ok = true;
3180         bool is_error = false;
3181
3182         try
3183         {
3184                 /* The specification is not clear about framebuffer completness. OpenGL 4.5 core profile
3185                  specification in chapter 9.4.2 says:
3186                  "The framebuffer object bound to target is said to be framebuffer complete if all
3187                  the following conditions are true [...]"
3188                  It does not say that framebuffer is incomplete when any of the conditions are not met.
3189                  Due to this wording, except for obvious cases (incomplete attachment and missing attachments)
3190                  other tests ar optional and may result in QP_TEST_RESULT_COMPATIBILITY_WARNING when fail. */
3191                 is_ok &= IncompleteAttachmentTestCase();
3192                 is_ok &= MissingAttachmentTestCase();
3193
3194                 maybe_ok &= IncompleteMultisampleRenderbufferTestCase();
3195                 maybe_ok &= IncompleteMultisampleTextureTestCase();
3196                 maybe_ok &= IncompleteLayerTargetsTestCase();
3197         }
3198         catch (...)
3199         {
3200                 is_ok   = false;
3201                 is_error = true;
3202         }
3203
3204         /* Errors clean up. */
3205         while (gl.getError())
3206                 ;
3207
3208         /* Result's setup. */
3209         if (is_ok)
3210         {
3211                 if (maybe_ok)
3212                 {
3213                         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3214                 }
3215                 else
3216                 {
3217                         m_testCtx.setTestResult(QP_TEST_RESULT_COMPATIBILITY_WARNING, "Pass with Compatibility Warning");
3218                 }
3219         }
3220         else
3221         {
3222                 if (is_error)
3223                 {
3224                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
3225                 }
3226                 else
3227                 {
3228                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3229                 }
3230         }
3231
3232         return STOP;
3233 }
3234
3235 /** Incomplete Attachment Test Case
3236  *
3237  *  @return True if test case succeeded, false otherwise.
3238  */
3239 bool CheckStatusTest::IncompleteAttachmentTestCase()
3240 {
3241         /* Shortcut for GL functionality. */
3242         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3243
3244         /* Test result */
3245         bool is_ok      = true;
3246         bool is_error = false;
3247
3248         /* Test objects. */
3249         glw::GLuint fbo = 0;
3250         glw::GLuint rbo = 0;
3251
3252         try
3253         {
3254                 gl.genFramebuffers(1, &fbo);
3255                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
3256
3257                 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3258                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3259
3260                 gl.genRenderbuffers(1, &rbo);
3261                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
3262
3263                 gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
3264                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
3265
3266                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
3267                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3268
3269                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3270                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3271
3272                 glw::GLenum status = 0;
3273
3274                 /* Check that framebuffer is complete. */
3275                 if (GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT != (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
3276                 {
3277                         m_context.getTestContext().getLog()
3278                                 << tcu::TestLog::Message
3279                                 << "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_ATTACHMENT value. "
3280                                 << glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;
3281
3282                         is_ok = false;
3283                 }
3284         }
3285         catch (...)
3286         {
3287                 is_ok   = false;
3288                 is_error = true;
3289         }
3290
3291         /* Releasing obnjects. */
3292         if (fbo)
3293         {
3294                 gl.deleteFramebuffers(1, &fbo);
3295         }
3296
3297         if (rbo)
3298         {
3299                 gl.deleteRenderbuffers(1, &rbo);
3300         }
3301
3302         if (is_error)
3303         {
3304                 throw 0;
3305         }
3306
3307         /* Errors clean up. */
3308         while (gl.getError())
3309                 ;
3310
3311         return is_ok;
3312 }
3313
3314 /** Missing Attachment Test Case
3315  *
3316  *  @return True if test case succeeded, false otherwise.
3317  */
3318 bool CheckStatusTest::MissingAttachmentTestCase()
3319 {
3320         /* Shortcut for GL functionality. */
3321         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3322
3323         /* Test result */
3324         bool is_ok      = true;
3325         bool is_error = false;
3326
3327         /* Test objects. */
3328         glw::GLuint fbo = 0;
3329
3330         try
3331         {
3332                 gl.genFramebuffers(1, &fbo);
3333                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
3334
3335                 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3336                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3337
3338                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3339                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3340
3341                 glw::GLenum status = 0;
3342
3343                 /* Check that framebuffer is complete. */
3344                 if (GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT !=
3345                         (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
3346                 {
3347                         m_context.getTestContext().getLog()
3348                                 << tcu::TestLog::Message
3349                                 << "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT value. "
3350                                 << glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;
3351
3352                         is_ok = false;
3353                 }
3354         }
3355         catch (...)
3356         {
3357                 is_ok   = false;
3358                 is_error = true;
3359         }
3360
3361         /* Releasing obnjects. */
3362         if (fbo)
3363         {
3364                 gl.deleteRenderbuffers(1, &fbo);
3365         }
3366
3367         if (is_error)
3368         {
3369                 throw 0;
3370         }
3371
3372         /* Errors clean up. */
3373         while (gl.getError())
3374                 ;
3375
3376         return is_ok;
3377 }
3378
3379 /** Incomplete Multisample Renderbuffer Test Case
3380  *
3381  *  @return True if test case succeeded, false otherwise.
3382  */
3383 bool CheckStatusTest::IncompleteMultisampleRenderbufferTestCase()
3384 {
3385         /* Shortcut for GL functionality. */
3386         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3387
3388         /* Test result */
3389         bool is_ok      = true;
3390         bool is_error = false;
3391
3392         /* Test objects. */
3393         glw::GLuint fbo = 0;
3394         glw::GLuint rbo[2] = { 0 };
3395
3396         try
3397         {
3398                 gl.genFramebuffers(1, &fbo);
3399                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
3400
3401                 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3402                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3403
3404                 gl.genRenderbuffers(2, rbo);
3405                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
3406
3407                 gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
3408                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
3409
3410                 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_R8, 1, 1);
3411                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
3412
3413                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
3414                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3415
3416                 gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
3417                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
3418
3419                 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_R8, 1, 1);
3420                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
3421
3422                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbo[1]);
3423                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3424
3425                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3426                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3427
3428                 glw::GLenum status = 0;
3429
3430                 /* Check that framebuffer is complete. */
3431                 if (GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE != (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
3432                 {
3433                         m_context.getTestContext().getLog()
3434                                 << tcu::TestLog::Message
3435                                 << "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_MULTISAMPLE value. "
3436                                 << glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;
3437
3438                         is_ok = false;
3439                 }
3440         }
3441         catch (...)
3442         {
3443                 is_ok   = false;
3444                 is_error = true;
3445         }
3446
3447         /* Releasing obnjects. */
3448         if (fbo)
3449         {
3450                 gl.deleteFramebuffers(1, &fbo);
3451         }
3452
3453         for (glw::GLuint i = 0; i < 2; ++i)
3454         {
3455                 if (rbo[i])
3456                 {
3457                         gl.deleteRenderbuffers(1, &rbo[i]);
3458                 }
3459         }
3460
3461         if (is_error)
3462         {
3463                 throw 0;
3464         }
3465
3466         /* Errors clean up. */
3467         while (gl.getError())
3468                 ;
3469
3470         return is_ok;
3471 }
3472
3473 /** Incomplete Multisample Texture Test Case
3474  *
3475  *  @return True if test case succeeded, false otherwise.
3476  */
3477 bool CheckStatusTest::IncompleteMultisampleTextureTestCase()
3478 {
3479         /* Shortcut for GL functionality. */
3480         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3481
3482         /* Test result */
3483         bool is_ok      = true;
3484         bool is_error = false;
3485
3486         /* Test objects. */
3487         glw::GLuint fbo   = 0;
3488         glw::GLuint rbo   = 0;
3489         glw::GLuint to[2] = { 0 };
3490
3491         try
3492         {
3493                 gl.genFramebuffers(1, &fbo);
3494                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
3495
3496                 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3497                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3498
3499                 gl.genTextures(2, to);
3500                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
3501
3502                 gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to[0]);
3503                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
3504
3505                 gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_R8, 1, 1, GL_FALSE);
3506                 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample has failed");
3507
3508                 gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to[0], 0);
3509                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3510
3511                 gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to[1]);
3512                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
3513
3514                 gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_R8, 1, 1, GL_TRUE);
3515                 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample has failed");
3516
3517                 gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to[1], 0);
3518                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3519
3520                 gl.genRenderbuffers(1, &rbo);
3521                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
3522
3523                 gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
3524                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
3525
3526                 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_R8, 1, 1);
3527                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
3528
3529                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rbo);
3530                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3531
3532                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3533                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3534
3535                 glw::GLenum status = 0;
3536
3537                 /* Check that framebuffer is complete. */
3538                 if (GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE != (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
3539                 {
3540                         m_context.getTestContext().getLog()
3541                                 << tcu::TestLog::Message
3542                                 << "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_MULTISAMPLE value. "
3543                                 << glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;
3544
3545                         is_ok = false;
3546                 }
3547         }
3548         catch (...)
3549         {
3550                 is_ok   = false;
3551                 is_error = true;
3552         }
3553
3554         /* Releasing obnjects. */
3555         if (fbo)
3556         {
3557                 gl.deleteFramebuffers(1, &fbo);
3558         }
3559
3560         for (glw::GLuint i = 0; i < 2; ++i)
3561         {
3562                 if (to[i])
3563                 {
3564                         gl.deleteTextures(1, &to[i]);
3565                 }
3566         }
3567
3568         if (rbo)
3569         {
3570                 gl.deleteRenderbuffers(1, &rbo);
3571         }
3572
3573         if (is_error)
3574         {
3575                 throw 0;
3576         }
3577
3578         /* Errors clean up. */
3579         while (gl.getError())
3580                 ;
3581
3582         return is_ok;
3583 }
3584
3585 /** Incomplete Layer Targets Test Case
3586  *
3587  *  @return True if test case succeeded, false otherwise.
3588  */
3589 bool CheckStatusTest::IncompleteLayerTargetsTestCase()
3590 {
3591         /* Shortcut for GL functionality. */
3592         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3593
3594         /* Test result */
3595         bool is_ok      = true;
3596         bool is_error = false;
3597
3598         /* Test objects. */
3599         glw::GLuint fbo   = 0;
3600         glw::GLuint to[2] = { 0 };
3601
3602         try
3603         {
3604                 gl.genFramebuffers(1, &fbo);
3605                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
3606
3607                 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3608                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3609
3610                 gl.genTextures(2, to);
3611                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
3612
3613                 gl.bindTexture(GL_TEXTURE_3D, to[0]);
3614                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
3615
3616                 gl.texStorage3D(GL_TEXTURE_3D, 1, GL_R8, 2, 2, 2);
3617                 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample has failed");
3618
3619                 gl.framebufferTexture3D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_3D, to[0], 0, 0);
3620                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3621
3622                 gl.bindTexture(GL_TEXTURE_2D, to[1]);
3623                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
3624
3625                 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8, 1, 1);
3626                 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample has failed");
3627
3628                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, to[1], 0);
3629                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3630
3631                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3632                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3633
3634                 glw::GLenum status = 0;
3635
3636                 /* Check that framebuffer is complete. */
3637                 if (GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS != (status = gl.checkNamedFramebufferStatus(fbo, GL_FRAMEBUFFER)))
3638                 {
3639                         m_context.getTestContext().getLog()
3640                                 << tcu::TestLog::Message
3641                                 << "CheckNamedFramebufferStatus did not return FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS value. "
3642                                 << glu::getFramebufferStatusStr(status) << " was observed instead." << tcu::TestLog::EndMessage;
3643
3644                         is_ok = false;
3645                 }
3646         }
3647         catch (...)
3648         {
3649                 is_ok   = false;
3650                 is_error = true;
3651         }
3652
3653         /* Releasing obnjects. */
3654         if (fbo)
3655         {
3656                 gl.deleteFramebuffers(1, &fbo);
3657         }
3658
3659         for (glw::GLuint i = 0; i < 2; ++i)
3660         {
3661                 if (to[i])
3662                 {
3663                         gl.deleteTextures(1, &to[i]);
3664                 }
3665         }
3666
3667         if (is_error)
3668         {
3669                 throw 0;
3670         }
3671
3672         /* Errors clean up. */
3673         while (gl.getError())
3674                 ;
3675
3676         return is_ok;
3677 }
3678
3679 /******************************** Get Named Framebuffer Parameters Test Implementation   ********************************/
3680
3681 /** @brief Get Named Framebuffer Parameters Test constructor.
3682  *
3683  *  @param [in] context     OpenGL context.
3684  */
3685 GetParametersTest::GetParametersTest(deqp::Context& context)
3686         : deqp::TestCase(context, "framebuffers_get_parameters", "Get Named Framebuffer Parameters Test")
3687         , m_fbo(0)
3688         , m_rbo(0)
3689 {
3690         /* Intentionally left blank. */
3691 }
3692
3693 /** @brief Iterate Check Status Test cases.
3694  *
3695  *  @return Iteration result.
3696  */
3697 tcu::TestNode::IterateResult GetParametersTest::iterate()
3698 {
3699         /* Shortcut for GL functionality. */
3700         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3701
3702         /* Get context setup. */
3703         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
3704         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
3705
3706         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
3707         {
3708                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
3709
3710                 return STOP;
3711         }
3712
3713         /* Running tests. */
3714         bool is_ok      = true;
3715         bool is_error = false;
3716
3717         try
3718         {
3719                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3720                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3721
3722                 is_ok &= TestDefaultFramebuffer();
3723
3724                 PrepareFramebuffer();
3725
3726                 is_ok &= TestCustomFramebuffer();
3727         }
3728         catch (...)
3729         {
3730                 is_ok   = false;
3731                 is_error = true;
3732         }
3733
3734         /* Clean up. */
3735         Clean();
3736
3737         /* Result's setup. */
3738         if (is_ok)
3739         {
3740                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3741         }
3742         else
3743         {
3744                 if (is_error)
3745                 {
3746                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
3747                 }
3748                 else
3749                 {
3750                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3751                 }
3752         }
3753
3754         return STOP;
3755 }
3756
3757 /** @brief Prepare framebuffer.
3758  */
3759 void GetParametersTest::PrepareFramebuffer()
3760 {
3761         /* Shortcut for GL functionality. */
3762         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3763
3764         gl.genFramebuffers(1, &m_fbo);
3765         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
3766
3767         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
3768         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
3769
3770         gl.genRenderbuffers(1, &m_rbo);
3771         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
3772
3773         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
3774         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
3775
3776         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, 1, 2);
3777         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
3778
3779         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
3780         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
3781
3782         /* Check that framebuffer is complete. */
3783         if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER))
3784         {
3785                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unexpectedly framebuffer was incomplete."
3786                                                                                         << tcu::TestLog::EndMessage;
3787
3788                 throw 0;
3789         }
3790 }
3791
3792 /** Default framebuffer Test Case
3793  *
3794  *  @return True if test case succeeded, false otherwise.
3795  */
3796 bool GetParametersTest::TestDefaultFramebuffer()
3797 {
3798         /* Shortcut for GL functionality. */
3799         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3800
3801         /* Result. */
3802         bool is_ok = true;
3803
3804         static const glw::GLenum pnames[] = { GL_DOUBLEBUFFER,
3805                                                                                   GL_IMPLEMENTATION_COLOR_READ_FORMAT,
3806                                                                                   GL_IMPLEMENTATION_COLOR_READ_TYPE,
3807                                                                                   GL_SAMPLES,
3808                                                                                   GL_SAMPLE_BUFFERS,
3809                                                                                   GL_STEREO };
3810
3811         static const glw::GLchar* pnames_strings[] = { "GL_DOUBLEBUFFER",
3812                                                                                                    "GL_IMPLEMENTATION_COLOR_READ_FORMAT",
3813                                                                                                    "GL_IMPLEMENTATION_COLOR_READ_TYPE",
3814                                                                                                    "GL_SAMPLES",
3815                                                                                                    "GL_SAMPLE_BUFFERS",
3816                                                                                                    "GL_STEREO" };
3817
3818         glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);
3819
3820         for (glw::GLuint i = 0; i < pnames_count; ++i)
3821         {
3822                 glw::GLint parameter_legacy = 0;
3823                 glw::GLint parameter_dsa        = 0;
3824
3825                 gl.getFramebufferParameteriv(GL_FRAMEBUFFER, pnames[i], &parameter_legacy);
3826                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");
3827
3828                 gl.getNamedFramebufferParameteriv(0, pnames[i], &parameter_dsa);
3829
3830                 if (glw::GLenum error = gl.getError())
3831                 {
3832                         m_context.getTestContext().getLog()
3833                                 << tcu::TestLog::Message << "GetNamedFramebufferParameteriv unexpectedly generated "
3834                                 << glu::getErrorStr(error) << " error when called with " << pnames_strings[i]
3835                                 << " parameter name for default framebuffer." << tcu::TestLog::EndMessage;
3836
3837                         is_ok = false;
3838
3839                         continue;
3840                 }
3841
3842                 if (parameter_legacy != parameter_dsa)
3843                 {
3844                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedFramebufferParameteriv returned "
3845                                                                                                 << parameter_dsa << ", but " << parameter_legacy << " was expected for "
3846                                                                                                 << pnames_strings[i] << " parameter name of default object."
3847                                                                                                 << tcu::TestLog::EndMessage;
3848
3849                         is_ok = false;
3850                 }
3851         }
3852
3853         return is_ok;
3854 }
3855
3856 /** Framebuffer Object Test Case
3857  *
3858  *  @return True if test case succeeded, false otherwise.
3859  */
3860 bool GetParametersTest::TestCustomFramebuffer()
3861 {
3862         /* Shortcut for GL functionality. */
3863         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3864
3865         /* Result. */
3866         bool is_ok = true;
3867
3868         static const glw::GLenum pnames[] = { GL_DOUBLEBUFFER,
3869                                                                                   GL_IMPLEMENTATION_COLOR_READ_FORMAT,
3870                                                                                   GL_IMPLEMENTATION_COLOR_READ_TYPE,
3871                                                                                   GL_SAMPLES,
3872                                                                                   GL_SAMPLE_BUFFERS,
3873                                                                                   GL_STEREO,
3874                                                                                   GL_FRAMEBUFFER_DEFAULT_WIDTH,
3875                                                                                   GL_FRAMEBUFFER_DEFAULT_HEIGHT,
3876                                                                                   GL_FRAMEBUFFER_DEFAULT_LAYERS,
3877                                                                                   GL_FRAMEBUFFER_DEFAULT_SAMPLES,
3878                                                                                   GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS };
3879
3880         static const glw::GLchar* pnames_strings[] = { "GL_DOUBLEBUFFER",
3881                                                                                                    "GL_IMPLEMENTATION_COLOR_READ_FORMAT",
3882                                                                                                    "GL_IMPLEMENTATION_COLOR_READ_TYPE",
3883                                                                                                    "GL_SAMPLES",
3884                                                                                                    "GL_SAMPLE_BUFFERS",
3885                                                                                                    "GL_STEREO",
3886                                                                                                    "FRAMEBUFFER_DEFAULT_WIDTH",
3887                                                                                                    "FRAMEBUFFER_DEFAULT_HEIGHT",
3888                                                                                                    "FRAMEBUFFER_DEFAULT_LAYERS",
3889                                                                                                    "FRAMEBUFFER_DEFAULT_SAMPLES",
3890                                                                                                    "FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS" };
3891
3892         glw::GLuint pnames_count = sizeof(pnames) / sizeof(pnames[0]);
3893
3894         for (glw::GLuint i = 0; i < pnames_count; ++i)
3895         {
3896                 glw::GLint parameter_legacy = 0;
3897                 glw::GLint parameter_dsa        = 0;
3898
3899                 gl.getFramebufferParameteriv(GL_FRAMEBUFFER, pnames[i], &parameter_legacy);
3900                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");
3901
3902                 gl.getNamedFramebufferParameteriv(m_fbo, pnames[i], &parameter_dsa);
3903
3904                 if (glw::GLenum error = gl.getError())
3905                 {
3906                         m_context.getTestContext().getLog()
3907                                 << tcu::TestLog::Message << "GetNamedFramebufferParameteriv unexpectedly generated "
3908                                 << glu::getErrorStr(error) << " error when called with " << pnames_strings[i]
3909                                 << " parameter name for framebuffer object." << tcu::TestLog::EndMessage;
3910
3911                         is_ok = false;
3912
3913                         continue;
3914                 }
3915
3916                 if (parameter_legacy != parameter_dsa)
3917                 {
3918                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetNamedFramebufferParameteriv returned "
3919                                                                                                 << parameter_dsa << ", but " << parameter_legacy << " was expected for "
3920                                                                                                 << pnames_strings[i] << " parameter name of framebuffer object."
3921                                                                                                 << tcu::TestLog::EndMessage;
3922
3923                         is_ok = false;
3924                 }
3925         }
3926
3927         return is_ok;
3928 }
3929
3930 /** @brief Clean up GL state.
3931  */
3932 void GetParametersTest::Clean()
3933 {
3934         /* Shortcut for GL functionality. */
3935         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3936
3937         /* Releasing obnjects. */
3938         if (m_fbo)
3939         {
3940                 gl.deleteFramebuffers(1, &m_fbo);
3941
3942                 m_fbo = 0;
3943         }
3944
3945         if (m_rbo)
3946         {
3947                 gl.deleteRenderbuffers(1, &m_rbo);
3948
3949                 m_rbo = 0;
3950         }
3951
3952         /* Errors clean up. */
3953         while (gl.getError())
3954                 ;
3955 }
3956
3957 /******************************** Get Named Framebuffer Attachment Parameters Test Implementation   ********************************/
3958
3959 /** @brief Get Named Framebuffer Parameters Test constructor.
3960  *
3961  *  @param [in] context     OpenGL context.
3962  */
3963 GetAttachmentParametersTest::GetAttachmentParametersTest(deqp::Context& context)
3964         : deqp::TestCase(context, "framebuffers_get_attachment_parameters",
3965                                          "Get Named Framebuffer Attachment Parameters Test")
3966         , m_fbo(0)
3967 {
3968         memset(m_rbo, 0, sizeof(m_rbo));
3969         memset(m_to, 0, sizeof(m_to));
3970 }
3971
3972 /** @brief Iterate Get Named Framebuffer Attachment Parameters Test cases.
3973  *
3974  *  @return Iteration result.
3975  */
3976 tcu::TestNode::IterateResult GetAttachmentParametersTest::iterate()
3977 {
3978         /* Shortcut for GL functionality. */
3979         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3980
3981         /* Get context setup. */
3982         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
3983         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
3984
3985         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
3986         {
3987                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
3988
3989                 return STOP;
3990         }
3991
3992         /* Running tests. */
3993         bool is_ok      = true;
3994         bool is_error = false;
3995
3996         try
3997         {
3998                 /* Default framebuffer. */
3999                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
4000                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
4001
4002                 is_ok &= TestDefaultFramebuffer();
4003
4004                 /* Framebuffer object with renderbuffer attachments (depth only). */
4005                 CreateRenderbufferFramebuffer(true, false);
4006
4007                 is_ok &= TestRenderbufferFramebuffer(false);
4008
4009                 Clean();
4010
4011                 /* Framebuffer object with renderbuffer attachments (stencil only). */
4012                 CreateRenderbufferFramebuffer(false, true);
4013
4014                 is_ok &= TestRenderbufferFramebuffer(false);
4015
4016                 Clean();
4017
4018                 /* Framebuffer object with renderbuffer attachments (depth-stencil merged). */
4019                 CreateRenderbufferFramebuffer(true, true);
4020
4021                 is_ok &= TestRenderbufferFramebuffer(true);
4022
4023                 Clean();
4024
4025                 /* Framebuffer object with texture attachments (depth only). */
4026                 CreateTextureFramebuffer(true, false);
4027
4028                 is_ok &= TestTextureFramebuffer(false);
4029
4030                 Clean();
4031
4032                 /* Framebuffer object with texture attachments (stencil only). */
4033                 CreateTextureFramebuffer(false, true);
4034
4035                 is_ok &= TestTextureFramebuffer(false);
4036
4037                 Clean();
4038
4039                 /* Framebuffer object with texture attachments (depth-stencil merged). */
4040                 CreateTextureFramebuffer(true, true);
4041
4042                 is_ok &= TestTextureFramebuffer(true);
4043
4044                 Clean();
4045         }
4046         catch (...)
4047         {
4048                 is_ok   = false;
4049                 is_error = true;
4050         }
4051
4052         /* Clean up. */
4053         Clean();
4054
4055         /* Result's setup. */
4056         if (is_ok)
4057         {
4058                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4059         }
4060         else
4061         {
4062                 if (is_error)
4063                 {
4064                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
4065                 }
4066                 else
4067                 {
4068                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4069                 }
4070         }
4071
4072         return STOP;
4073 }
4074
4075 /** Create framebuffer with renderbuffer
4076  *
4077  *  @param [in] depth   Prepare framebuffer with depth buffer.
4078  *  @param [in] stencil   Prepare framebuffer with stencil buffer.
4079  *
4080  *  @note If both depth and stencil, the joined dept_stencil buffer will be created.
4081  */
4082 void GetAttachmentParametersTest::CreateRenderbufferFramebuffer(bool depth, bool stencil)
4083 {
4084         /* Shortcut for GL functionality. */
4085         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4086
4087         gl.genFramebuffers(1, &m_fbo);
4088         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
4089
4090         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
4091         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
4092
4093         gl.genRenderbuffers(2, m_rbo);
4094         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
4095
4096         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[0]);
4097         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
4098
4099         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 2);
4100         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
4101
4102         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo[0]);
4103         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
4104
4105         if (depth && (!stencil))
4106         {
4107                 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[1]);
4108                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
4109
4110                 gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 1, 2);
4111                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
4112
4113                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbo[1]);
4114                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
4115         }
4116
4117         if ((!depth) && stencil)
4118         {
4119                 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[1]);
4120                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
4121
4122                 gl.renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 1, 2);
4123                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
4124
4125                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo[1]);
4126                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
4127         }
4128
4129         if (depth && stencil)
4130         {
4131                 gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo[1]);
4132                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
4133
4134                 gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1, 2);
4135                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
4136
4137                 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo[1]);
4138                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
4139         }
4140
4141         /* Check that framebuffer is complete. */
4142         if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER))
4143         {
4144                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unexpectedly framebuffer was incomplete."
4145                                                                                         << tcu::TestLog::EndMessage;
4146
4147                 throw 0;
4148         }
4149 }
4150
4151 /** Create framebuffer with tetxure
4152  *
4153  *  @param [in] depth   Prepare framebuffer with depth buffer.
4154  *  @param [in] stencil   Prepare framebuffer with stencil buffer.
4155  *
4156  *  @note If both depth and stencil, the joined dept_stencil buffer will be created.
4157  */
4158 void GetAttachmentParametersTest::CreateTextureFramebuffer(bool depth, bool stencil)
4159 {
4160         /* Shortcut for GL functionality. */
4161         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4162
4163         gl.genFramebuffers(1, &m_fbo);
4164         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
4165
4166         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
4167         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffers has failed");
4168
4169         gl.genTextures(2, m_to);
4170         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
4171
4172         gl.bindTexture(GL_TEXTURE_2D, m_to[0]);
4173         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
4174
4175         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 2);
4176         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
4177
4178         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to[0], 0);
4179         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
4180
4181         if (depth && (!stencil))
4182         {
4183                 gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
4184                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
4185
4186                 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT24, 1, 2);
4187                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
4188
4189                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_to[1], 0);
4190                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
4191         }
4192
4193         if ((!depth) && stencil)
4194         {
4195                 gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
4196                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
4197
4198                 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_STENCIL_INDEX8, 1, 2);
4199                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
4200
4201                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_to[1], 0);
4202                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
4203         }
4204
4205         if (depth && stencil)
4206         {
4207                 gl.bindTexture(GL_TEXTURE_2D, m_to[1]);
4208                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffers has failed");
4209
4210                 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 1, 2);
4211                 GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
4212
4213                 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_to[1], 0);
4214                 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
4215         }
4216
4217         /* Check that framebuffer is complete. */
4218         if (GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER))
4219         {
4220                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Unexpectedly framebuffer was incomplete."
4221                                                                                         << tcu::TestLog::EndMessage;
4222
4223                 throw 0;
4224         }
4225 }
4226
4227 /** Test default framebuffer.
4228  *
4229  *  @return True if test succeeded, false otherwise.
4230  */
4231 bool GetAttachmentParametersTest::TestDefaultFramebuffer()
4232 {
4233         /* Shortcut for GL functionality. */
4234         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4235
4236         /* Result. */
4237         bool is_ok = true;
4238
4239         static const glw::GLenum attachments[] = { GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK_LEFT,
4240                                                                                            GL_BACK_RIGHT, GL_DEPTH,               GL_STENCIL };
4241
4242         static const glw::GLchar* attachments_strings[] = { "GL_FRONT_LEFT", "GL_FRONT_RIGHT", "GL_BACK_LEFT",
4243                                                                                                                 "GL_BACK_RIGHT", "GL_DEPTH",       "GL_STENCIL" };
4244
4245         static const glw::GLuint attachments_count = sizeof(attachments) / sizeof(attachments[0]);
4246
4247         for (glw::GLuint j = 0; j < attachments_count; ++j)
4248         {
4249                 glw::GLint parameter_legacy = 0;
4250                 glw::GLint parameter_dsa        = 0;
4251
4252                 gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
4253                                                                                            &parameter_legacy);
4254                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");
4255
4256                 gl.getNamedFramebufferAttachmentParameteriv(0, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
4257                                                                                                         &parameter_dsa);
4258
4259                 /* Error check. */
4260                 if (glw::GLenum error = gl.getError())
4261                 {
4262                         m_context.getTestContext().getLog()
4263                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
4264                                 << glu::getErrorStr(error)
4265                                 << " error when called with GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter name for "
4266                                 << attachments_strings[j] << " attachment of default framebuffer." << tcu::TestLog::EndMessage;
4267
4268                         is_ok = false;
4269
4270                         continue;
4271                 }
4272
4273                 if (parameter_legacy != parameter_dsa)
4274                 {
4275                         m_context.getTestContext().getLog()
4276                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned " << parameter_dsa
4277                                 << ", but " << parameter_legacy
4278                                 << " was expected for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter name of default framebuffer."
4279                                 << tcu::TestLog::EndMessage;
4280
4281                         is_ok = false;
4282
4283                         continue;
4284                 }
4285
4286                 if (parameter_dsa != GL_NONE)
4287                 {
4288                         static const glw::GLenum optional_pnames[] = {
4289                                 GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,               GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
4290                                 GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,      GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
4291                                 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,    GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
4292                                 GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
4293                         };
4294
4295                         static const glw::GLchar* optional_pnames_strings[] = {
4296                                 "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",           "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
4297                                 "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",          "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
4298                                 "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",         "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
4299                                 "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE", "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING"
4300                         };
4301
4302                         static const glw::GLuint optional_pnames_count = sizeof(optional_pnames) / sizeof(optional_pnames[0]);
4303
4304                         for (glw::GLuint i = 0; i < optional_pnames_count; ++i)
4305                         {
4306                                 glw::GLint optional_parameter_legacy = 0;
4307                                 glw::GLint optional_parameter_dsa       = 0;
4308
4309                                 gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], optional_pnames[i],
4310                                                                                                            &optional_parameter_legacy);
4311                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");
4312
4313                                 gl.getNamedFramebufferAttachmentParameteriv(0, attachments[j], optional_pnames[i],
4314                                                                                                                         &optional_parameter_dsa);
4315
4316                                 if (glw::GLenum error = gl.getError())
4317                                 {
4318                                         m_context.getTestContext().getLog()
4319                                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
4320                                                 << glu::getErrorStr(error) << " error when called with " << optional_pnames_strings[i]
4321                                                 << " parameter name for " << attachments_strings[j]
4322                                                 << " attachment of default framebuffer. The GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE was "
4323                                                 << parameter_legacy << "." << tcu::TestLog::EndMessage;
4324
4325                                         is_ok = false;
4326
4327                                         continue;
4328                                 }
4329
4330                                 if (optional_parameter_legacy != optional_parameter_dsa)
4331                                 {
4332                                         m_context.getTestContext().getLog()
4333                                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned "
4334                                                 << optional_parameter_dsa << ", but " << optional_parameter_legacy << " was expected for "
4335                                                 << optional_pnames_strings << " parameter name  for " << attachments_strings[j]
4336                                                 << " attachment of default framebuffer." << tcu::TestLog::EndMessage;
4337
4338                                         is_ok = false;
4339
4340                                         continue;
4341                                 }
4342                         }
4343                 }
4344         }
4345
4346         return is_ok;
4347 }
4348
4349 /** Test framebuffer object (with renderbuffer).
4350  *
4351  *  @param [in] depth_stencil       Has framebuffer depth_stencil attachment.
4352  *
4353  *  @return True if test succeeded, false otherwise.
4354  */
4355 bool GetAttachmentParametersTest::TestRenderbufferFramebuffer(bool depth_stencil)
4356 {
4357         /* Shortcut for GL functionality. */
4358         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4359
4360         /* Result. */
4361         bool is_ok = true;
4362
4363         static const glw::GLenum attachments[] = { GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL_ATTACHMENT,
4364                                                                                            GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
4365
4366         static const glw::GLchar* attachments_strings[] = { "GL_DEPTH_ATTACHMENT", "GL_STENCIL_ATTACHMENT",
4367                                                                                                                 "GL_DEPTH_STENCIL_ATTACHMENT", "GL_COLOR_ATTACHMENT0",
4368                                                                                                                 "GL_COLOR_ATTACHMENT1" };
4369
4370         static const glw::GLuint attachments_count = sizeof(attachments) / sizeof(attachments[0]);
4371
4372         for (glw::GLuint j = 0; j < attachments_count; ++j)
4373         {
4374                 glw::GLint parameter_legacy = 0;
4375                 glw::GLint parameter_dsa        = 0;
4376
4377                 /* Omit DEPTH_STENCIL_ATTACHMENT attachment if the renderbuffer is not depth-stencil. */
4378                 if (attachments[j] == GL_DEPTH_STENCIL_ATTACHMENT)
4379                 {
4380                         if (!depth_stencil)
4381                         {
4382                                 continue;
4383                         }
4384                 }
4385
4386                 gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
4387                                                                                            &parameter_legacy);
4388                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");
4389
4390                 gl.getNamedFramebufferAttachmentParameteriv(m_fbo, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
4391                                                                                                         &parameter_dsa);
4392
4393                 /* Error check. */
4394                 if (glw::GLenum error = gl.getError())
4395                 {
4396                         m_context.getTestContext().getLog()
4397                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
4398                                 << glu::getErrorStr(error)
4399                                 << " error when called with GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter name for "
4400                                 << attachments_strings[j] << " attachment of renderbuffer framebuffer object."
4401                                 << tcu::TestLog::EndMessage;
4402
4403                         is_ok = false;
4404
4405                         continue;
4406                 }
4407
4408                 if (parameter_legacy != parameter_dsa)
4409                 {
4410                         m_context.getTestContext().getLog()
4411                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned " << parameter_dsa
4412                                 << ", but " << parameter_legacy << " was expected for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter "
4413                                                                                                    "name of renderbuffer framebuffer object."
4414                                 << tcu::TestLog::EndMessage;
4415
4416                         is_ok = false;
4417
4418                         continue;
4419                 }
4420
4421                 if (parameter_dsa != GL_NONE)
4422                 {
4423                         static const glw::GLenum optional_pnames[] = {
4424                                 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,   GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
4425                                 GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,   GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
4426                                 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,   GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
4427                                 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,  GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
4428                                 GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING
4429                         };
4430
4431                         static const glw::GLchar* optional_pnames_strings[] = {
4432                                 "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",   "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",
4433                                 "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE", "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
4434                                 "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE", "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
4435                                 "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",  "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",
4436                                 "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING"
4437                         };
4438
4439                         static const glw::GLuint optional_pnames_count = sizeof(optional_pnames) / sizeof(optional_pnames[0]);
4440
4441                         for (glw::GLuint i = 0; i < optional_pnames_count; ++i)
4442                         {
4443                                 /* Omit FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE pname when DEPTH_STENCIL_ATTACHMENT attachment is used. */
4444                                 if (attachments[j] == GL_DEPTH_STENCIL_ATTACHMENT)
4445                                 {
4446                                         if (optional_pnames[i] == GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE)
4447                                         {
4448                                                 continue;
4449                                         }
4450                                 }
4451
4452                                 glw::GLint optional_parameter_legacy = 0;
4453                                 glw::GLint optional_parameter_dsa       = 0;
4454
4455                                 gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], optional_pnames[i],
4456                                                                                                            &optional_parameter_legacy);
4457                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");
4458
4459                                 gl.getNamedFramebufferAttachmentParameteriv(m_fbo, attachments[j], optional_pnames[i],
4460                                                                                                                         &optional_parameter_dsa);
4461
4462                                 if (glw::GLenum error = gl.getError())
4463                                 {
4464                                         m_context.getTestContext().getLog()
4465                                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
4466                                                 << glu::getErrorStr(error) << " error when called with " << optional_pnames_strings[i]
4467                                                 << " parameter name for " << attachments_strings[j]
4468                                                 << " attachment of renderbuffer framebuffer object. The GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE "
4469                                                    "was "
4470                                                 << parameter_legacy << "." << tcu::TestLog::EndMessage;
4471
4472                                         is_ok = false;
4473
4474                                         continue;
4475                                 }
4476
4477                                 if (optional_parameter_legacy != optional_parameter_dsa)
4478                                 {
4479                                         m_context.getTestContext().getLog()
4480                                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned "
4481                                                 << optional_parameter_dsa << ", but " << optional_parameter_legacy << " was expected for "
4482                                                 << optional_pnames_strings << " parameter name  for " << attachments_strings[j]
4483                                                 << " attachment of renderbuffer framebuffer object." << tcu::TestLog::EndMessage;
4484
4485                                         is_ok = false;
4486
4487                                         continue;
4488                                 }
4489                         }
4490                 }
4491         }
4492
4493         return is_ok;
4494 }
4495
4496 /** Test framebuffer object (with texture).
4497  *
4498  *  @param [in] depth_stencil       Has framebuffer depth_stencil attachment.
4499  *
4500  *  @return True if test succeeded, false otherwise.
4501  */
4502 bool GetAttachmentParametersTest::TestTextureFramebuffer(bool depth_stencil)
4503 {
4504         /* Shortcut for GL functionality. */
4505         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4506
4507         /* Result. */
4508         bool is_ok = true;
4509
4510         static const glw::GLenum attachments[] = { GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL_ATTACHMENT,
4511                                                                                            GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
4512
4513         static const glw::GLchar* attachments_strings[] = { "GL_DEPTH_ATTACHMENT", "GL_STENCIL_ATTACHMENT",
4514                                                                                                                 "GL_DEPTH_STENCIL_ATTACHMENT", "GL_COLOR_ATTACHMENT0",
4515                                                                                                                 "GL_COLOR_ATTACHMENT1" };
4516
4517         static const glw::GLuint attachments_count = sizeof(attachments) / sizeof(attachments[0]);
4518
4519         for (glw::GLuint j = 0; j < attachments_count; ++j)
4520         {
4521                 /* Omit DEPTH_STENCIL_ATTACHMENT attachment if the renderbuffer is not depth-stencil. */
4522                 if (attachments[j] == GL_DEPTH_STENCIL_ATTACHMENT)
4523                 {
4524                         if (!depth_stencil)
4525                         {
4526                                 continue;
4527                         }
4528                 }
4529
4530                 glw::GLint parameter_legacy = 0;
4531                 glw::GLint parameter_dsa        = 0;
4532
4533                 gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
4534                                                                                            &parameter_legacy);
4535                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");
4536
4537                 gl.getNamedFramebufferAttachmentParameteriv(m_fbo, attachments[j], GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
4538                                                                                                         &parameter_dsa);
4539
4540                 /* Error check. */
4541                 if (glw::GLenum error = gl.getError())
4542                 {
4543                         m_context.getTestContext().getLog()
4544                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
4545                                 << glu::getErrorStr(error)
4546                                 << " error when called with GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter name for "
4547                                 << attachments_strings[j] << " attachment of texture framebuffer object." << tcu::TestLog::EndMessage;
4548
4549                         is_ok = false;
4550
4551                         continue;
4552                 }
4553
4554                 if (parameter_legacy != parameter_dsa)
4555                 {
4556                         m_context.getTestContext().getLog()
4557                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned " << parameter_dsa
4558                                 << ", but " << parameter_legacy << " was expected for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE parameter "
4559                                                                                                    "name of texture framebuffer object."
4560                                 << tcu::TestLog::EndMessage;
4561
4562                         is_ok = false;
4563
4564                         continue;
4565                 }
4566
4567                 if (parameter_dsa != GL_NONE)
4568                 {
4569                         static const glw::GLenum optional_pnames[] = { GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
4570                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
4571                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
4572                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_LAYERED,
4573                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER,
4574                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
4575                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
4576                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
4577                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
4578                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
4579                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
4580                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
4581                                                                                                                    GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING };
4582
4583                         static const glw::GLchar* optional_pnames_strings[] = { "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
4584                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
4585                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
4586                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_LAYERED",
4587                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",
4588                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",
4589                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
4590                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
4591                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
4592                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
4593                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
4594                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",
4595                                                                                                                                         "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING" };
4596
4597                         static const glw::GLuint optional_pnames_count = sizeof(optional_pnames) / sizeof(optional_pnames[0]);
4598
4599                         for (glw::GLuint i = 0; i < optional_pnames_count; ++i)
4600                         {
4601                                 /* Omit FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE pname when DEPTH_STENCIL_ATTACHMENT attachment is used. */
4602                                 if (attachments[j] == GL_DEPTH_STENCIL_ATTACHMENT)
4603                                 {
4604                                         if (optional_pnames[i] == GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE)
4605                                         {
4606                                                 continue;
4607                                         }
4608                                 }
4609
4610                                 glw::GLint optional_parameter_legacy = 0;
4611                                 glw::GLint optional_parameter_dsa       = 0;
4612
4613                                 gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, attachments[j], optional_pnames[i],
4614                                                                                                            &optional_parameter_legacy);
4615                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferParameteriv has failed");
4616
4617                                 gl.getNamedFramebufferAttachmentParameteriv(m_fbo, attachments[j], optional_pnames[i],
4618                                                                                                                         &optional_parameter_dsa);
4619
4620                                 if (glw::GLenum error = gl.getError())
4621                                 {
4622                                         m_context.getTestContext().getLog()
4623                                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv unexpectedly generated "
4624                                                 << glu::getErrorStr(error) << " error when called with " << optional_pnames_strings[i]
4625                                                 << " parameter name for " << attachments_strings[j]
4626                                                 << " attachment of texture framebuffer object. The GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE was "
4627                                                 << parameter_legacy << "." << tcu::TestLog::EndMessage;
4628
4629                                         is_ok = false;
4630
4631                                         continue;
4632                                 }
4633
4634                                 if (optional_parameter_legacy != optional_parameter_dsa)
4635                                 {
4636                                         m_context.getTestContext().getLog()
4637                                                 << tcu::TestLog::Message << "GetNamedFramebufferAttachmentParameteriv returned "
4638                                                 << optional_parameter_dsa << ", but " << optional_parameter_legacy << " was expected for "
4639                                                 << optional_pnames_strings << " parameter name  for " << attachments_strings[j]
4640                                                 << " attachment of texture framebuffer object." << tcu::TestLog::EndMessage;
4641
4642                                         is_ok = false;
4643
4644                                         continue;
4645                                 }
4646                         }
4647                 }
4648         }
4649
4650         return is_ok;
4651 }
4652
4653 /** @brief Clean up GL state.
4654  */
4655 void GetAttachmentParametersTest::Clean()
4656 {
4657         /* Shortcut for GL functionality. */
4658         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4659
4660         /* Releasing obnjects. */
4661         if (m_fbo)
4662         {
4663                 gl.deleteFramebuffers(1, &m_fbo);
4664
4665                 m_fbo = 0;
4666         }
4667
4668         /* Releasing renderbuffers. */
4669         for (glw::GLuint i = 0; i < 2; ++i)
4670         {
4671                 if (m_rbo[i])
4672                 {
4673                         gl.deleteRenderbuffers(1, &m_rbo[i]);
4674
4675                         m_rbo[i] = 0;
4676                 }
4677         }
4678
4679         /* Releasing textures. */
4680         for (glw::GLuint i = 0; i < 2; ++i)
4681         {
4682                 if (m_to[i])
4683                 {
4684                         gl.deleteTextures(1, &m_to[i]);
4685
4686                         m_to[i] = 0;
4687                 }
4688         }
4689
4690         /* Errors clean up. */
4691         while (gl.getError())
4692                 ;
4693 }
4694
4695 /******************************** Framebuffer Creation Errors Test Implementation   ********************************/
4696
4697 /** @brief Creation Errors Test constructor.
4698  *
4699  *  @param [in] context     OpenGL context.
4700  */
4701 CreationErrorsTest::CreationErrorsTest(deqp::Context& context)
4702         : deqp::TestCase(context, "framebuffers_creation_errors", "Framebuffer Objects Creation Errors Test")
4703 {
4704         /* Intentionally left blank. */
4705 }
4706
4707 /** @brief Iterate Creation Test cases.
4708  *
4709  *  @return Iteration result.
4710  */
4711 tcu::TestNode::IterateResult CreationErrorsTest::iterate()
4712 {
4713         /* Shortcut for GL functionality. */
4714         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4715
4716         /* Get context setup. */
4717         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
4718         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
4719
4720         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
4721         {
4722                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
4723
4724                 return STOP;
4725         }
4726
4727         /* Running tests. */
4728         bool is_ok = true;
4729
4730         /* Framebuffer object */
4731         glw::GLuint framebuffer = 0;
4732
4733         /* Check direct state creation of negative numbers of framebuffers. */
4734         gl.createFramebuffers(-1, &framebuffer);
4735
4736         glw::GLenum error = GL_NO_ERROR;
4737
4738         if (GL_INVALID_VALUE != (error = gl.getError()))
4739         {
4740                 m_context.getTestContext().getLog()
4741                         << tcu::TestLog::Message << "CreateFramebuffers generated " << glu::getErrorStr(error)
4742                         << " error when called with negative number of framebuffers, but GL_INVALID_VALUE was expected."
4743                         << tcu::TestLog::EndMessage;
4744
4745                 is_ok = false;
4746         }
4747
4748         /* Cleanup (sanity). */
4749         if (framebuffer)
4750         {
4751                 gl.deleteFramebuffers(1, &framebuffer);
4752         }
4753
4754         /* Errors clean up. */
4755         while (gl.getError())
4756                 ;
4757
4758         /* Result's setup. */
4759         if (is_ok)
4760         {
4761                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4762         }
4763         else
4764         {
4765                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4766         }
4767
4768         return STOP;
4769 }
4770
4771 /******************************** Renderbuffer Attachment Errors Test Implementation   ********************************/
4772
4773 /** @brief Renderbuffer Attachment Errors Test constructor.
4774  *
4775  *  @param [in] context     OpenGL context.
4776  */
4777 RenderbufferAttachmentErrorsTest::RenderbufferAttachmentErrorsTest(deqp::Context& context)
4778         : deqp::TestCase(context, "framebuffers_renderbuffer_attachment_errors", "Renderbuffer Attachment Errors Test")
4779         , m_fbo_valid(0)
4780         , m_rbo_valid(0)
4781         , m_fbo_invalid(0)
4782         , m_rbo_invalid(0)
4783         , m_color_attachment_invalid(0)
4784         , m_attachment_invalid(0)
4785         , m_renderbuffer_target_invalid(0)
4786 {
4787         /* Intentionally left blank. */
4788 }
4789
4790 /** @brief Iterate Renderbuffer Attachment Errors Test cases.
4791  *
4792  *  @return Iteration result.
4793  */
4794 tcu::TestNode::IterateResult RenderbufferAttachmentErrorsTest::iterate()
4795 {
4796         /* Shortcut for GL functionality. */
4797         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4798
4799         /* Get context setup. */
4800         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
4801         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
4802
4803         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
4804         {
4805                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
4806
4807                 return STOP;
4808         }
4809
4810         /* Running tests. */
4811         bool is_ok      = true;
4812         bool is_error = false;
4813
4814         try
4815         {
4816                 /* Prepare objects. */
4817                 PrepareObjects();
4818
4819                 /* Invalid Framebuffer ID. */
4820                 gl.namedFramebufferRenderbuffer(m_fbo_invalid, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_valid);
4821
4822                 is_ok &= ExpectError(GL_INVALID_OPERATION, false, true, false, true, true);
4823
4824                 /* Invalid color attachment. */
4825                 gl.namedFramebufferRenderbuffer(m_fbo_valid, m_color_attachment_invalid, GL_RENDERBUFFER, m_rbo_valid);
4826
4827                 is_ok &= ExpectError(GL_INVALID_OPERATION, true, false, true, true, true);
4828
4829                 /* Invalid attachment. */
4830                 gl.namedFramebufferRenderbuffer(m_fbo_valid, m_attachment_invalid, GL_RENDERBUFFER, m_rbo_valid);
4831
4832                 is_ok &= ExpectError(GL_INVALID_ENUM, true, false, false, true, true);
4833
4834                 /* Invalid Renderbuffer Target. */
4835                 gl.namedFramebufferRenderbuffer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_renderbuffer_target_invalid, m_rbo_valid);
4836
4837                 is_ok &= ExpectError(GL_INVALID_ENUM, true, true, false, false, true);
4838
4839                 /* Invalid Renderbuffer ID. */
4840                 gl.namedFramebufferRenderbuffer(m_fbo_valid, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_invalid);
4841
4842                 is_ok &= ExpectError(GL_INVALID_OPERATION, true, true, false, true, false);
4843         }
4844         catch (...)
4845         {
4846                 is_ok   = false;
4847                 is_error = true;
4848         }
4849
4850         /* Cleanup. */
4851         Clean();
4852
4853         /* Result's setup. */
4854         if (is_ok)
4855         {
4856                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4857         }
4858         else
4859         {
4860                 if (is_error)
4861                 {
4862                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
4863                 }
4864                 else
4865                 {
4866                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4867                 }
4868         }
4869
4870         return STOP;
4871 }
4872
4873 /** Prepare test objects.
4874  */
4875 void RenderbufferAttachmentErrorsTest::PrepareObjects()
4876 {
4877         /* Shortcut for GL functionality. */
4878         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4879
4880         /* Valid objects. */
4881         gl.genFramebuffers(1, &m_fbo_valid);
4882         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
4883
4884         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
4885         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
4886
4887         gl.genRenderbuffers(1, &m_rbo_valid);
4888         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
4889
4890         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_valid);
4891         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
4892
4893         /* Invalid objects. */
4894         while (gl.isFramebuffer(++m_fbo_invalid))
4895                 ;
4896         while (gl.isRenderbuffer(++m_rbo_invalid))
4897                 ;
4898
4899         /* Max color attachments query. */
4900         glw::GLint max_color_attachments = 8; /* Spec default. */
4901         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
4902         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
4903
4904         /* Invalid color attachment */
4905         m_color_attachment_invalid = GL_COLOR_ATTACHMENT0 + max_color_attachments;
4906
4907         /* Invalid attachment. */
4908         bool is_attachment = true;
4909
4910         while (is_attachment)
4911         {
4912                 ++m_attachment_invalid;
4913
4914                 is_attachment = false;
4915
4916                 if ((GL_DEPTH_ATTACHMENT == m_attachment_invalid) || (GL_STENCIL_ATTACHMENT == m_attachment_invalid) ||
4917                         (GL_DEPTH_STENCIL_ATTACHMENT == m_attachment_invalid))
4918                 {
4919                         is_attachment = true;
4920                 }
4921
4922                 if (GL_COLOR_ATTACHMENT0 < m_attachment_invalid)
4923                 {
4924                         /* If this unlikely happen this mean that we cannot create invalid attachment which is not DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT and
4925                          GL_COLOR_ATTACHMENTm where m IS any positive integer number (for m < MAX_COLOR_ATTACHMENTS attachments are valid, and for m >= MAX_COLOR_ATTACHMENTS is invalid, but
4926                          INVALID_OPERATION shall be generated instead of INVALID_ENUM. Such a situation may need change in the test or in the specification. */
4927                         throw 0;
4928                 }
4929         }
4930
4931         /* Invalid renderbuffer target. */
4932         m_renderbuffer_target_invalid = GL_RENDERBUFFER + 1;
4933 }
4934
4935 /** Check if error is equal to the expected, log if not.
4936  *
4937  *  @param [in] expected_error      Error to be expected.
4938  *  @param [in] framebuffer         Framebuffer name to be logged.
4939  *  @param [in] attachment          Attachment name to be logged.
4940  *  @param [in] renderbuffertarget  Renderbuffertarget name to be logged.
4941  *  @param [in] renderbuffer        Renderbuffer name to be logged.
4942  *
4943  *  @return True if test succeeded, false otherwise.
4944  */
4945 bool RenderbufferAttachmentErrorsTest::ExpectError(glw::GLenum expected_error, bool framebuffer, bool attachment,
4946                                                                                                    bool color_attachment, bool renderbuffertarget, bool renderbuffer)
4947 {
4948         /* Shortcut for GL functionality. */
4949         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4950
4951         bool is_ok = true;
4952
4953         glw::GLenum error = GL_NO_ERROR;
4954
4955         if (expected_error != (error = gl.getError()))
4956         {
4957                 m_context.getTestContext().getLog()
4958                         << tcu::TestLog::Message << "NamedFramebufferRenderbuffer called with "
4959                         << (framebuffer ? "valid" : "invalid") << " framebuffer, " << (attachment ? "valid" : "invalid")
4960                         << (color_attachment ? " color" : "") << " attachment, " << (renderbuffertarget ? "valid" : "invalid")
4961                         << " renderbuffer target, " << (renderbuffer ? "valid" : "invalid")
4962                         << " renderbuffer was expected to generate " << glu::getErrorStr(expected_error) << ", but "
4963                         << glu::getErrorStr(error) << " was observed instead." << tcu::TestLog::EndMessage;
4964
4965                 is_ok = false;
4966         }
4967
4968         /* Clean additional possible errors. */
4969         while (gl.getError())
4970                 ;
4971
4972         return is_ok;
4973 }
4974
4975 /** @brief Clean up GL state.
4976  */
4977 void RenderbufferAttachmentErrorsTest::Clean()
4978 {
4979         /* Shortcut for GL functionality. */
4980         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4981
4982         /* Release GL objects. */
4983         if (m_fbo_valid)
4984         {
4985                 gl.deleteFramebuffers(1, &m_fbo_valid);
4986                 m_fbo_valid = 0;
4987         }
4988
4989         if (m_rbo_valid)
4990         {
4991                 gl.deleteRenderbuffers(1, &m_rbo_valid);
4992                 m_rbo_valid = 0;
4993         }
4994
4995         /* Set initial values - all test shall have the same environment. */
4996         m_fbo_invalid                             = 0;
4997         m_rbo_invalid                             = 0;
4998         m_attachment_invalid              = 0;
4999         m_color_attachment_invalid      = 0;
5000         m_renderbuffer_target_invalid = 0;
5001
5002         /* Errors clean up. */
5003         while (gl.getError())
5004                 ;
5005 }
5006
5007 /******************************** Texture Attachment Errors Test Implementation   ********************************/
5008
5009 /** @brief Texture Attachment Errors Test constructor.
5010  *
5011  *  @param [in] context     OpenGL context.
5012  */
5013 TextureAttachmentErrorsTest::TextureAttachmentErrorsTest(deqp::Context& context)
5014         : deqp::TestCase(context, "framebuffers_texture_attachment_errors", "Texture Attachment Errors Test")
5015         , m_fbo_valid(0)
5016         , m_to_valid(0)
5017         , m_to_3d_valid(0)
5018         , m_to_array_valid(0)
5019         , m_to_cubearray_valid(0)
5020         , m_tbo_valid(0)
5021         , m_fbo_invalid(0)
5022         , m_to_invalid(0)
5023         , m_to_layer_invalid(0)
5024         , m_color_attachment_invalid(0)
5025         , m_attachment_invalid(0)
5026         , m_level_invalid(0)
5027         , m_max_3d_texture_size(2048)            /* OpenGL 4.5 Core Profile default values (Table 23.53). */
5028         , m_max_3d_texture_depth(2048)           /* == m_max_3d_texture_size or value of GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV. */
5029         , m_max_array_texture_layers(2048)   /* OpenGL 4.5 Core Profile default values (Table 23.53). */
5030         , m_max_cube_map_texture_size(16384) /* OpenGL 4.5 Core Profile default values (Table 23.53). */
5031 {
5032         /* Intentionally left blank. */
5033 }
5034
5035 /** @brief Iterate Texture Attachment Errors Test cases.
5036  *
5037  *  @return Iteration result.
5038  */
5039 tcu::TestNode::IterateResult TextureAttachmentErrorsTest::iterate()
5040 {
5041         /* Shortcut for GL functionality. */
5042         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5043
5044         /* Get context setup. */
5045         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5046         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5047
5048         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5049         {
5050                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5051
5052                 return STOP;
5053         }
5054
5055         /* Running tests. */
5056         bool is_ok      = true;
5057         bool is_error = false;
5058
5059         try
5060         {
5061                 /* Prepare objects. */
5062                 PrepareObjects();
5063
5064                 /********** NamedFramebufferTexture **************/
5065
5066                 /* Invalid Framebuffer ID. */
5067                 gl.namedFramebufferTexture(m_fbo_invalid, GL_COLOR_ATTACHMENT0, m_to_valid, 0);
5068
5069                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTexture", false, true, false, true, true, "", true);
5070
5071                 /* Invalid Color Attachment. */
5072                 gl.namedFramebufferTexture(m_fbo_valid, m_color_attachment_invalid, m_to_valid, 0);
5073
5074                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTexture", true, false, true, true, true, "", true);
5075
5076                 /* Invalid Attachment. */
5077                 gl.namedFramebufferTexture(m_fbo_valid, m_attachment_invalid, m_to_valid, 0);
5078
5079                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferTexture", true, false, false, true, true, "", true);
5080
5081                 /* Invalid Texture ID. */
5082                 gl.namedFramebufferTexture(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_invalid, 0);
5083
5084                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTexture", true, true, false, false, true, "", true);
5085
5086                 /* Invalid Level. */
5087                 gl.namedFramebufferTexture(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_valid, m_level_invalid);
5088
5089                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTexture", true, true, false, true, false, "", true);
5090
5091                 /* Buffer texture. */
5092                 gl.namedFramebufferTexture(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_tbo_valid, 0);
5093
5094                 is_ok &=
5095                         ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTexture", true, true, false, true, true, "buffer", true);
5096
5097                 /********** NamedFramebufferTextureLayer **************/
5098
5099                 /* Invalid Framebuffer ID. */
5100                 gl.namedFramebufferTextureLayer(m_fbo_invalid, GL_COLOR_ATTACHMENT0, m_to_array_valid, 0, 0);
5101
5102                 is_ok &=
5103                         ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", false, true, false, true, true, "", true);
5104
5105                 /* Invalid Color Attachment. */
5106                 gl.namedFramebufferTextureLayer(m_fbo_valid, m_color_attachment_invalid, m_to_array_valid, 0, 0);
5107
5108                 is_ok &=
5109                         ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", true, false, true, true, true, "", true);
5110
5111                 /* Invalid Attachment. */
5112                 gl.namedFramebufferTextureLayer(m_fbo_valid, m_attachment_invalid, m_to_array_valid, 0, 0);
5113
5114                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferTextureLayer", true, false, false, true, true, "", true);
5115
5116                 /* Invalid Texture ID. */
5117                 gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_invalid, 0, 0);
5118
5119                 is_ok &=
5120                         ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", true, true, false, false, true, "", true);
5121
5122                 /* Invalid Level. */
5123                 gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_array_valid, m_level_invalid, 0);
5124
5125                 is_ok &=
5126                         ExpectError(GL_INVALID_VALUE, "NamedFramebufferTextureLayer", true, true, false, true, false, "", true);
5127
5128                 /* Buffer texture. */
5129                 gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_tbo_valid, 0, 0);
5130
5131                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", true, true, false, true, true,
5132                                                          "buffer", true);
5133
5134                 /* Check that INVALID_VALUE error is generated by NamedFramebufferTextureLayer if texture is a three-dimensional
5135                  texture, and layer is larger than the value of MAX_3D_TEXTURE_SIZE or GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV (if available) minus one. */
5136                 gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_3d_valid, 0, m_max_3d_texture_depth);
5137
5138                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTextureLayer", true, true, false, true, true,
5139                                                          "3D texture", false);
5140
5141                 /* Check that INVALID_VALUE error is generated by NamedFramebufferTextureLayer if texture is an array texture,
5142                  and layer is larger than the value of MAX_ARRAY_TEXTURE_LAYERS minus one. */
5143                 gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_array_valid, 0,
5144                                                                                 m_max_array_texture_layers);
5145
5146                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTextureLayer", true, true, false, true, true, "array",
5147                                                          false);
5148
5149                 /* Check that INVALID_VALUE error is generated by NamedFramebufferTextureLayer if texture is a cube map array texture,
5150                  and (layer / 6) is larger than the value of MAX_CUBE_MAP_TEXTURE_SIZE minus one (see section 9.8).
5151                  Check that INVALID_VALUE error is generated by NamedFramebufferTextureLayer if texture is non-zero
5152                  and layer is negative. */
5153                 gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_cubearray_valid, 0,
5154                                                                                 m_max_cube_map_texture_size);
5155
5156                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferTextureLayer", true, true, false, true, true,
5157                                                          "cuba map array", false);
5158
5159                 /* Check that INVALID_OPERATION error is generated by NamedFramebufferTextureLayer if texture is non-zero
5160                  and is not the name of a three-dimensional, two-dimensional multisample array, one- or two-dimensional array,
5161                  or cube map array texture. */
5162                 gl.namedFramebufferTextureLayer(m_fbo_valid, GL_COLOR_ATTACHMENT0, m_to_layer_invalid, 0, 0);
5163
5164                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferTextureLayer", true, true, false, false, true,
5165                                                          "rectangle", true);
5166         }
5167         catch (...)
5168         {
5169                 is_ok   = false;
5170                 is_error = true;
5171         }
5172
5173         /* Cleanup. */
5174         Clean();
5175
5176         /* Result's setup. */
5177         if (is_ok)
5178         {
5179                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5180         }
5181         else
5182         {
5183                 if (is_error)
5184                 {
5185                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5186                 }
5187                 else
5188                 {
5189                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5190                 }
5191         }
5192
5193         return STOP;
5194 }
5195
5196 /** Prepare test GL objects.
5197  */
5198 void TextureAttachmentErrorsTest::PrepareObjects()
5199 {
5200         /* Shortcut for GL functionality. */
5201         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5202
5203         /* Valid objects. */
5204         gl.genFramebuffers(1, &m_fbo_valid);
5205         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
5206
5207         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
5208         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
5209
5210         gl.genTextures(1, &m_to_valid);
5211         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
5212
5213         gl.bindTexture(GL_TEXTURE_2D, m_to_valid);
5214         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
5215
5216         gl.genTextures(1, &m_tbo_valid);
5217         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
5218
5219         gl.bindTexture(GL_TEXTURE_BUFFER, m_tbo_valid);
5220         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
5221
5222         gl.genTextures(1, &m_to_3d_valid);
5223         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
5224
5225         gl.bindTexture(GL_TEXTURE_3D, m_to_3d_valid);
5226         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
5227
5228         gl.genTextures(1, &m_to_array_valid);
5229         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
5230
5231         gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_array_valid);
5232         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
5233
5234         gl.genTextures(1, &m_to_cubearray_valid);
5235         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
5236
5237         gl.bindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_to_cubearray_valid);
5238         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
5239
5240         gl.genTextures(1, &m_to_layer_invalid);
5241         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
5242
5243         gl.bindTexture(GL_TEXTURE_RECTANGLE, m_to_layer_invalid);
5244         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
5245
5246         /* Invalid objects. */
5247         while (gl.isFramebuffer(++m_fbo_invalid))
5248                 ;
5249         while (gl.isTexture(++m_to_invalid))
5250                 ;
5251
5252         /* Max color attachments query. */
5253         glw::GLint max_color_attachments = 8; /* Spec default. */
5254         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
5255         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
5256
5257         /* Invalid color attachment */
5258         m_color_attachment_invalid = GL_COLOR_ATTACHMENT0 + max_color_attachments;
5259
5260         /* Invalid attachment. */
5261         bool is_attachment = true;
5262
5263         while (is_attachment)
5264         {
5265                 ++m_attachment_invalid;
5266
5267                 is_attachment = false;
5268
5269                 if ((GL_DEPTH_ATTACHMENT == m_attachment_invalid) || (GL_STENCIL_ATTACHMENT == m_attachment_invalid) ||
5270                         (GL_DEPTH_STENCIL_ATTACHMENT == m_attachment_invalid))
5271                 {
5272                         is_attachment = true;
5273                 }
5274
5275                 for (glw::GLint i = 0; i < max_color_attachments; ++i)
5276                 {
5277                         if (GL_COLOR_ATTACHMENT0 == m_attachment_invalid)
5278                         {
5279                                 is_attachment = true;
5280                         }
5281                 }
5282         }
5283
5284         /* Maximum values */
5285         gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE, &m_max_3d_texture_size);
5286         gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &m_max_array_texture_layers);
5287         gl.getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &m_max_cube_map_texture_size);
5288
5289         if (m_context.getContextInfo().isExtensionSupported("GL_NV_deep_texture3D"))
5290         {
5291                 gl.getIntegerv(GL_MAX_DEEP_3D_TEXTURE_DEPTH_NV, &m_max_3d_texture_depth);
5292         }
5293         else
5294         {
5295                 m_max_3d_texture_depth = m_max_3d_texture_size;
5296         }
5297
5298         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
5299
5300         /* Invalid level. */
5301         m_level_invalid = -1;
5302 }
5303
5304 /** Check if error is equal to the expected, log if not.
5305  *
5306  *  @param [in] expected_error      Error to be expected.
5307  *  @param [in] framebuffer         Framebuffer name to be logged.
5308  *  @param [in] attachment          Attachment name to be logged.
5309  *  @param [in] texture             Texture name to be logged.
5310  *  @param [in] level               Level # to be logged.
5311  *  @param [in] buffer_texture      Is this buffer texture (special logging case).
5312  *
5313  *  @return True if test succeeded, false otherwise.
5314  */
5315 bool TextureAttachmentErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function_name,
5316                                                                                           bool framebuffer, bool attachment, bool color_attachment, bool texture,
5317                                                                                           bool level, const glw::GLchar* texture_type, bool layer)
5318 {
5319         /* Shortcut for GL functionality. */
5320         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5321
5322         bool is_ok = true;
5323
5324         glw::GLenum error = GL_NO_ERROR;
5325
5326         if (expected_error != (error = gl.getError()))
5327         {
5328                 m_context.getTestContext().getLog()
5329                         << tcu::TestLog::Message << function_name << " called with " << (framebuffer ? "valid" : "invalid")
5330                         << " framebuffer, " << (attachment ? "valid" : "invalid") << (color_attachment ? " color" : "")
5331                         << " attachment, " << (texture ? "valid " : "invalid ") << texture_type << " texture, "
5332                         << (level ? "valid" : "invalid") << " level" << (layer ? "" : ", with invalid layer number")
5333                         << " was expected to generate " << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
5334                         << " was observed instead." << tcu::TestLog::EndMessage;
5335
5336                 is_ok = false;
5337         }
5338
5339         /* Clean additional possible errors. */
5340         while (gl.getError())
5341                 ;
5342
5343         return is_ok;
5344 }
5345
5346 /** @brief Clean up GL state.
5347  */
5348 void TextureAttachmentErrorsTest::Clean()
5349 {
5350         /* Shortcut for GL functionality. */
5351         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5352
5353         /* Release GL objects. */
5354         if (m_fbo_valid)
5355         {
5356                 gl.deleteFramebuffers(1, &m_fbo_valid);
5357                 m_fbo_valid = 0;
5358         }
5359
5360         if (m_to_valid)
5361         {
5362                 gl.deleteTextures(1, &m_to_valid);
5363                 m_to_valid = 0;
5364         }
5365
5366         if (m_tbo_valid)
5367         {
5368                 gl.deleteTextures(1, &m_tbo_valid);
5369                 m_tbo_valid = 0;
5370         }
5371
5372         if (m_to_3d_valid)
5373         {
5374                 gl.deleteTextures(1, &m_to_3d_valid);
5375                 m_to_3d_valid = 0;
5376         }
5377
5378         if (m_to_array_valid)
5379         {
5380                 gl.deleteTextures(1, &m_to_array_valid);
5381                 m_to_array_valid = 0;
5382         }
5383
5384         if (m_to_cubearray_valid)
5385         {
5386                 gl.deleteTextures(1, &m_to_cubearray_valid);
5387                 m_to_cubearray_valid = 0;
5388         }
5389
5390         if (m_to_layer_invalid)
5391         {
5392                 gl.deleteTextures(1, &m_to_layer_invalid);
5393                 m_to_layer_invalid = 0;
5394         }
5395
5396         /* Set initial values - all test shall have the same environment. */
5397         m_fbo_invalid            = 0;
5398         m_to_invalid             = 0;
5399         m_attachment_invalid = 0;
5400         m_level_invalid          = 0;
5401
5402         m_max_3d_texture_size           = 2048;
5403         m_max_3d_texture_depth          = m_max_3d_texture_size;
5404         m_max_array_texture_layers  = 2048;
5405         m_max_cube_map_texture_size = 16384;
5406
5407         /* Errors clean up. */
5408         while (gl.getError())
5409                 ;
5410 }
5411
5412 /******************************** Draw Read Buffers Errors Test Implementation   ********************************/
5413
5414 /** @brief Draw Read Buffers Errors Test constructor.
5415  *
5416  *  @param [in] context     OpenGL context.
5417  */
5418 DrawReadBuffersErrorsTest::DrawReadBuffersErrorsTest(deqp::Context& context)
5419         : deqp::TestCase(context, "framebuffers_draw_read_buffers_errors", "Draw Read Buffers Errors Test Test")
5420         , m_fbo_valid(0)
5421         , m_fbo_invalid(0)
5422         , m_attachment_color(GL_COLOR_ATTACHMENT0)
5423         , m_attachment_back_left(GL_BACK_LEFT)
5424         , m_attachment_right(GL_RIGHT)
5425         , m_attachment_left(GL_LEFT)
5426         , m_attachment_front(GL_FRONT)
5427         , m_attachment_front_and_back(GL_FRONT_AND_BACK)
5428         , m_attachment_back(GL_BACK)
5429         , m_attachment_invalid(0)
5430         , m_max_color_attachments(8) /* GL 4.5 default, updated later */
5431 {
5432         m_attachments_invalid[0] = 0;
5433         m_attachments_invalid[1] = 0;
5434
5435         m_attachments_back_invalid[0] = GL_BACK_LEFT;
5436         m_attachments_back_invalid[1] = GL_BACK;
5437
5438         m_attachments_too_many_count = 0;
5439
5440         m_attachments_too_many = DE_NULL;
5441 }
5442
5443 /** @brief Iterate Draw Read Buffers Errors Test cases.
5444  *
5445  *  @return Iteration result.
5446  */
5447 tcu::TestNode::IterateResult DrawReadBuffersErrorsTest::iterate()
5448 {
5449         /* Shortcut for GL functionality. */
5450         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5451
5452         /* Get context setup. */
5453         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5454         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5455
5456         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5457         {
5458                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5459
5460                 return STOP;
5461         }
5462
5463         /* Running tests. */
5464         bool is_ok      = true;
5465         bool is_error = false;
5466
5467         try
5468         {
5469                 /* Prepare objects. */
5470                 PrepareObjects();
5471
5472                 /*  Check that INVALID_OPERATION error is generated by
5473                  NamedFramebufferDrawBuffer if framebuffer is not zero or the name of an
5474                  existing framebuffer object. */
5475                 gl.namedFramebufferDrawBuffer(m_fbo_invalid, m_attachment_color);
5476
5477                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffer",
5478                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
5479
5480                 /*  Check that INVALID_ENUM is generated by NamedFramebufferDrawBuffer if
5481                  buf is not an accepted value. */
5482                 gl.namedFramebufferDrawBuffer(m_fbo_valid, m_attachment_invalid);
5483
5484                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffer", "buf is not an accepted value.");
5485
5486                 /*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffer
5487                  if the GL is bound to a draw framebuffer object and the ith argument is
5488                  a value other than COLOR_ATTACHMENTi or NONE. */
5489                 gl.namedFramebufferDrawBuffer(m_fbo_valid, m_attachment_back_left);
5490
5491                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffer",
5492                                                          "the GL is bound to a draw framebuffer object and the ith argument is a value other than "
5493                                                          "COLOR_ATTACHMENTi or NONE.");
5494
5495                 /*  Check that INVALID_OPERATION error is generated by
5496                  NamedFramebufferDrawBuffers if framebuffer is not zero or the name of an
5497                  existing framebuffer object. */
5498                 gl.namedFramebufferDrawBuffers(m_fbo_invalid, 1, &m_attachment_color);
5499
5500                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
5501                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
5502
5503                 /*  Check that INVALID_VALUE is generated by NamedFramebufferDrawBuffers if n
5504                  is less than 0. */
5505                 gl.namedFramebufferDrawBuffers(m_fbo_valid, -1, &m_attachment_color);
5506
5507                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferDrawBuffers", "n is less than 0.");
5508
5509                 /*  Check that INVALID_VALUE is generated by NamedFramebufferDrawBuffers if
5510                  n is greater than MAX_DRAW_BUFFERS. */
5511                 gl.namedFramebufferDrawBuffers(m_fbo_valid, m_attachments_too_many_count, m_attachments_too_many);
5512
5513                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedFramebufferDrawBuffers", "n is greater than MAX_DRAW_BUFFERS.");
5514
5515                 /*  Check that INVALID_ENUM is generated by NamedFramebufferDrawBuffers if
5516                  one of the values in bufs is not an accepted value. */
5517                 gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_invalid);
5518
5519                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5520                                                          "one of the values in bufs is not an accepted value.");
5521
5522                 /*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffers
5523                  if a symbolic constant other than GL_NONE appears more than once in
5524                  bufs. */
5525                 gl.namedFramebufferDrawBuffers(m_fbo_valid, 2, m_attachments_invalid);
5526
5527                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
5528                                                          "a symbolic constant other than GL_NONE appears more than once in bufs.");
5529
5530                 /*  Check that INVALID_ENUM error is generated by NamedFramebufferDrawBuffers if any value in bufs is FRONT, LEFT, RIGHT, or FRONT_AND_BACK.
5531                  This restriction applies to both the default framebuffer and framebuffer objects, and exists because these constants may themselves
5532                  refer to multiple buffers, as shown in table 17.4. */
5533                 gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_front);
5534
5535                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5536                                                          "a framebuffer object is tested and a value in bufs is FRONT.");
5537
5538                 gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_left);
5539
5540                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5541                                                          "a framebuffer object is tested and a value in bufs is LEFT.");
5542
5543                 gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_right);
5544
5545                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5546                                                          "a framebuffer object is tested and a value in bufs is RIGHT.");
5547
5548                 gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_front_and_back);
5549
5550                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5551                                                          "a framebuffer object is tested and a value in bufs is FRONT_AND_BACK.");
5552
5553                 gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_front);
5554
5555                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5556                                                          "a default framebuffer is tested and a value in bufs is FRONT.");
5557
5558                 gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_left);
5559
5560                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5561                                                          "a default framebuffer is tested and a value in bufs is LEFT.");
5562
5563                 gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_right);
5564
5565                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5566                                                          "a default framebuffer is tested and a value in bufs is RIGHT.");
5567
5568                 gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_front_and_back);
5569
5570                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedFramebufferDrawBuffers",
5571                                                          "a default framebuffer is tested and a value in bufs is FRONT_AND_BACK.");
5572
5573                 /*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffers
5574                  if any value in bufs is BACK, and n is not one. */
5575                 gl.namedFramebufferDrawBuffers(0, 2, m_attachments_back_invalid);
5576
5577                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
5578                                                          "any value in bufs is BACK, and n is not one.");
5579
5580                 /*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffers if
5581                  the API call refers to a framebuffer object and one or more of the
5582                  values in bufs is anything other than NONE or one of the
5583                  COLOR_ATTACHMENTn tokens. */
5584                 gl.namedFramebufferDrawBuffers(m_fbo_valid, 1, &m_attachment_back_left);
5585
5586                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
5587                                                          "the API call refers to a framebuffer object and one or more of the values in bufs is "
5588                                                          "anything other than NONE or one of the COLOR_ATTACHMENTn tokens.");
5589
5590                 /*  Check that INVALID_OPERATION is generated by NamedFramebufferDrawBuffers if
5591                  the API call refers to the default framebuffer and one or more of the
5592                  values in bufs is one of the COLOR_ATTACHMENTn tokens. */
5593                 gl.namedFramebufferDrawBuffers(0, 1, &m_attachment_color);
5594
5595                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferDrawBuffers",
5596                                                          "the API call refers to the default framebuffer and one or more of the values in bufs is "
5597                                                          "one of the COLOR_ATTACHMENTn tokens.");
5598
5599                 /*  Check that INVALID_OPERATION is generated by NamedFramebufferReadBuffer
5600                  if framebuffer is not zero or the name of an existing framebuffer
5601                  object. */
5602                 gl.namedFramebufferReadBuffer(m_fbo_invalid, m_attachment_color);
5603
5604                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferReadBuffer",
5605                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
5606
5607                 /*  Check that INVALID_ENUM is generated by NamedFramebufferReadBuffer if
5608                  src is not one of the accepted values (tables 17.4 and 17.5 of OpenGL 4.5 Core Profile Specification). */
5609                 gl.namedFramebufferReadBuffer(m_fbo_valid, m_attachment_invalid);
5610
5611                 is_ok &= ExpectError(
5612                         GL_INVALID_ENUM, "NamedFramebufferReadBuffer",
5613                         "src is not one of the accepted values (tables 17.4 and 17.5 of OpenGL 4.5 Core Profile Specification).");
5614
5615                 /* Check that INVALID_OPERATION error is generated by NamedFramebufferReadBuffer if the default framebuffer is
5616                  affected and src is a value (other than NONE) that does not indicate any of the
5617                  color buffers allocated to the default framebuffer. */
5618                 gl.namedFramebufferReadBuffer(0, GL_COLOR_ATTACHMENT0);
5619
5620                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferReadBuffer",
5621                                                          "the default framebuffer is affected and src is a value (other than NONE) that does not "
5622                                                          "indicate any of the color buffers allocated to the default framebuffer.");
5623
5624                 /* Check that INVALID_OPERATION error is generated by NamedFramebufferReadBuffer if a framebuffer object is
5625                  affected, and src is one of the  constants from table 17.4 (other than NONE, or COLOR_ATTACHMENTm where m
5626                  is greater than or equal to the value of MAX_COLOR_ATTACHMENTS). */
5627                 gl.namedFramebufferReadBuffer(m_fbo_valid, m_attachment_front_and_back);
5628
5629                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferReadBuffer",
5630                                                          "a framebuffer object is affected, and src is one of the  constants from table 17.4.");
5631
5632                 gl.namedFramebufferReadBuffer(m_fbo_valid, GL_COLOR_ATTACHMENT0 + m_max_color_attachments);
5633
5634                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedFramebufferReadBuffer",
5635                                                          "a framebuffer object is affected, and src is one of the COLOR_ATTACHMENTm where mis "
5636                                                          "greater than or equal to the value of MAX_COLOR_ATTACHMENTS.");
5637         }
5638         catch (...)
5639         {
5640                 is_ok   = false;
5641                 is_error = true;
5642         }
5643
5644         /* Cleanup. */
5645         Clean();
5646
5647         /* Result's setup. */
5648         if (is_ok)
5649         {
5650                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5651         }
5652         else
5653         {
5654                 if (is_error)
5655                 {
5656                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5657                 }
5658                 else
5659                 {
5660                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5661                 }
5662         }
5663
5664         return STOP;
5665 }
5666
5667 /** Check Prepare test's GL objects.
5668  */
5669 void DrawReadBuffersErrorsTest::PrepareObjects()
5670 {
5671         /* Shortcut for GL functionality. */
5672         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5673
5674         /* Valid objects. */
5675         gl.genFramebuffers(1, &m_fbo_valid);
5676         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
5677
5678         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
5679         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
5680
5681         /* Invalid objects. */
5682         while (gl.isFramebuffer(++m_fbo_invalid))
5683                 ;
5684
5685         /* Invalid attachment. */
5686         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &m_max_color_attachments);
5687
5688         bool is_attachment = true;
5689
5690         while (is_attachment)
5691         {
5692                 ++m_attachment_invalid;
5693
5694                 is_attachment = false;
5695
5696                 /* Valid attachments are those from tables 17.4, 17.5 and a 17.6 (valid for various functions and framebuffer types).
5697                  (see OpenGL 4.5 Core Profile Specification) */
5698                 switch (m_attachment_invalid)
5699                 {
5700                 case GL_NONE:
5701                 case GL_FRONT_LEFT:
5702                 case GL_FRONT_RIGHT:
5703                 case GL_BACK_LEFT:
5704                 case GL_BACK_RIGHT:
5705                 case GL_FRONT:
5706                 case GL_BACK:
5707                 case GL_LEFT:
5708                 case GL_RIGHT:
5709                 case GL_FRONT_AND_BACK:
5710                         is_attachment = true;
5711                 };
5712
5713                 for (glw::GLint i = 0; i < m_max_color_attachments; ++i)
5714                 {
5715                         if ((glw::GLenum)(GL_COLOR_ATTACHMENT0 + i) == m_attachment_invalid)
5716                         {
5717                                 is_attachment = true;
5718                                 break;
5719                         }
5720                 }
5721         }
5722
5723         m_attachments_invalid[0] = GL_COLOR_ATTACHMENT0;
5724         m_attachments_invalid[1] = GL_COLOR_ATTACHMENT0;
5725
5726         glw::GLint max_draw_buffers = 8; /* Spec default. */
5727         gl.getIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
5728
5729         m_attachments_too_many_count = max_draw_buffers + 1;
5730
5731         m_attachments_too_many = new glw::GLenum[m_attachments_too_many_count];
5732
5733         m_attachments_too_many[0] = GL_COLOR_ATTACHMENT0;
5734
5735         for (glw::GLint i = 1; i < m_attachments_too_many_count; ++i)
5736         {
5737                 m_attachments_too_many[i] = GL_NONE;
5738         }
5739 }
5740
5741 /** Check if error is equal to the expected, log if not.
5742  *
5743  *  @param [in] expected_error      Error to be expected.
5744  *  @param [in] function            Function name which is being tested (to be logged).
5745  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
5746  *
5747  *  @return True if there is no error, false otherwise.
5748  */
5749 bool DrawReadBuffersErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
5750                                                                                         const glw::GLchar* conditions)
5751 {
5752         /* Shortcut for GL functionality. */
5753         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5754
5755         bool is_ok = true;
5756
5757         glw::GLenum error = GL_NO_ERROR;
5758
5759         if (expected_error != (error = gl.getError()))
5760         {
5761                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
5762                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
5763                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
5764
5765                 is_ok = false;
5766         }
5767
5768         /* Clean additional possible errors. */
5769         while (gl.getError())
5770                 ;
5771
5772         return is_ok;
5773 }
5774
5775 /** @brief Clean up GL state.
5776  */
5777 void DrawReadBuffersErrorsTest::Clean()
5778 {
5779         /* Shortcut for GL functionality. */
5780         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5781
5782         /* Release GL objects. */
5783         if (m_fbo_valid)
5784         {
5785                 gl.deleteFramebuffers(1, &m_fbo_valid);
5786                 m_fbo_valid = 0;
5787         }
5788
5789         /* Set initial values - all test shall have the same environment. */
5790         m_fbo_invalid                    = 0;
5791         m_attachment_invalid     = 0;
5792         m_attachments_invalid[0] = 0;
5793         m_attachments_invalid[1] = 0;
5794
5795         delete m_attachments_too_many;
5796
5797         m_attachments_too_many = DE_NULL;
5798
5799         m_attachments_too_many_count = 0;
5800
5801         /* Errors clean up. */
5802         while (gl.getError())
5803                 ;
5804 }
5805
5806 /******************************** Invalidate Data and SubData Errors Test Implementation   ********************************/
5807
5808 /** @brief Invalidate SubData Errors Test constructor.
5809  *
5810  *  @param [in] context     OpenGL context.
5811  */
5812 InvalidateDataAndSubDataErrorsTest::InvalidateDataAndSubDataErrorsTest(deqp::Context& context)
5813         : deqp::TestCase(context, "invalidate_data_and_subdata_errors", "Invalidate Data and SubData Errors Test")
5814         , m_fbo_valid(0)
5815         , m_rbo(0)
5816         , m_fbo_invalid(0)
5817         , m_fbo_attachment_valid(0)
5818         , m_fbo_attachment_invalid(0)
5819         , m_color_attachment_invalid(0)
5820         , m_default_attachment_invalid(0)
5821
5822 {
5823 }
5824
5825 /** @brief Iterate Invalidate Data and SubData Errors Test cases.
5826  *
5827  *  @return Iteration result.
5828  */
5829 tcu::TestNode::IterateResult InvalidateDataAndSubDataErrorsTest::iterate()
5830 {
5831         /* Shortcut for GL functionality. */
5832         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5833
5834         /* Get context setup. */
5835         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
5836         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
5837
5838         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
5839         {
5840                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
5841
5842                 return STOP;
5843         }
5844
5845         /* Running tests. */
5846         bool is_ok      = true;
5847         bool is_error = false;
5848
5849         try
5850         {
5851                 /* Prepare objects. */
5852                 PrepareObjects();
5853
5854                 /******* InvalidateNamedFramebufferData *******/
5855
5856                 /*  Check that INVALID_OPERATION error is generated by InvalidateNamedFramebufferData if framebuffer is not zero or the name of an existing framebuffer object. */
5857                 gl.invalidateNamedFramebufferData(m_fbo_invalid, 1, &m_fbo_attachment_valid);
5858
5859                 is_ok &= ExpectError(GL_INVALID_OPERATION, "InvalidateNamedFramebufferData",
5860                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
5861
5862                 /*  Check that INVALID_ENUM error is generated by InvalidateNamedFramebufferData if a framebuffer object is affected, and
5863                  any element of of attachments is not one of the values in table {COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT }. */
5864                 gl.invalidateNamedFramebufferData(m_fbo_valid, 1, &m_fbo_attachment_invalid);
5865
5866                 is_ok &= ExpectError(GL_INVALID_ENUM, "InvalidateNamedFramebufferData",
5867                                                          "a framebuffer object is affected, and any element of of attachments is not one of the "
5868                                                          "values in table { COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, "
5869                                                          "DEPTH_STENCIL_ATTACHMENT }.");
5870
5871                 /*  Check that INVALID_OPERATION error is generated by InvalidateNamedFramebufferData if attachments contains COLOR_ATTACHMENTm
5872                  where m is greater than or equal to the value of MAX_COLOR_ATTACHMENTS. */
5873                 gl.invalidateNamedFramebufferData(m_fbo_valid, 1, &m_color_attachment_invalid);
5874
5875                 is_ok &= ExpectError(GL_INVALID_OPERATION, "InvalidateNamedFramebufferData",
5876                                                          "attachments contains COLOR_ATTACHMENTm where m is greater than or equal to the value of "
5877                                                          "MAX_COLOR_ATTACHMENTS");
5878
5879                 /*  Check that INVALID_ENUM error is generated by
5880                  InvalidateNamedFramebufferData if the default framebuffer is affected,
5881                  and any elements of attachments are not one of:
5882                  -  FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, and BACK_RIGHT, identifying that
5883                  specific buffer,
5884                  -  COLOR, which is treated as BACK_LEFT for a double-buffered context
5885                  and FRONT_LEFT for a single-buffered context,
5886                  -  DEPTH, identifying the depth buffer,
5887                  -  STENCIL, identifying the stencil buffer. */
5888                 gl.invalidateNamedFramebufferData(0, 1, &m_default_attachment_invalid);
5889
5890                 is_ok &= ExpectError(GL_INVALID_ENUM, "InvalidateNamedFramebufferData",
5891                                                          "the default framebuffer is affected, and any elements of attachments are not one of "
5892                                                          "FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, COLOR, DEPTH, STENCIL.");
5893
5894                 /******* InvalidateNamedFramebufferSubData *******/
5895
5896                 /*  Check that INVALID_OPERATION error is generated by InvalidateNamedFramebufferSubData if framebuffer is not zero or the name of an existing framebuffer object. */
5897                 gl.invalidateNamedFramebufferSubData(m_fbo_invalid, 1, &m_fbo_attachment_valid, 0, 0, 1, 1);
5898
5899                 is_ok &= ExpectError(GL_INVALID_OPERATION, "InvalidateNamedFramebufferSubData",
5900                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
5901
5902                 /*  Check that INVALID_VALUE error is generated by InvalidateNamedFramebufferSubData if numAttachments, width, or height is negative. */
5903                 gl.invalidateNamedFramebufferSubData(m_fbo_valid, -1, &m_fbo_attachment_valid, 0, 0, 1, 1);
5904
5905                 is_ok &= ExpectError(GL_INVALID_VALUE, "InvalidateNamedFramebufferSubData", "numAttachments is negative.");
5906
5907                 gl.invalidateNamedFramebufferSubData(m_fbo_valid, 1, &m_fbo_attachment_valid, 0, 0, -1, 1);
5908
5909                 is_ok &= ExpectError(GL_INVALID_VALUE, "InvalidateNamedFramebufferSubData", "width is negative.");
5910
5911                 gl.invalidateNamedFramebufferSubData(m_fbo_valid, 1, &m_fbo_attachment_valid, 0, 0, 1, -1);
5912
5913                 is_ok &= ExpectError(GL_INVALID_VALUE, "InvalidateNamedFramebufferSubData", "height is negative.");
5914
5915                 /*  Check that INVALID_ENUM error is generated by InvalidateNamedFramebufferSubData if a framebuffer object is affected, and
5916                  any element of of attachments is not one of the values in table {COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT }. */
5917                 gl.invalidateNamedFramebufferSubData(m_fbo_valid, 1, &m_fbo_attachment_invalid, 0, 0, 1, 1);
5918
5919                 is_ok &= ExpectError(GL_INVALID_ENUM, "InvalidateNamedFramebufferSubData",
5920                                                          "a framebuffer object is affected, and any element of of attachments is not one of the "
5921                                                          "values in table { COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, "
5922                                                          "DEPTH_STENCIL_ATTACHMENT }.");
5923
5924                 /*  Check that INVALID_OPERATION error is generated by InvalidateNamedFramebufferSubData if attachments contains COLOR_ATTACHMENTm
5925                  where m is greater than or equal to the value of MAX_COLOR_ATTACHMENTS. */
5926                 gl.invalidateNamedFramebufferSubData(m_fbo_valid, 1, &m_color_attachment_invalid, 0, 0, 1, 1);
5927
5928                 is_ok &= ExpectError(GL_INVALID_OPERATION, "InvalidateNamedFramebufferSubData",
5929                                                          "attachments contains COLOR_ATTACHMENTm where m is greater than or equal to the value of "
5930                                                          "MAX_COLOR_ATTACHMENTS");
5931
5932                 /*  Check that INVALID_ENUM error is generated by InvalidateNamedFramebufferSubData if the default framebuffer is affected,
5933                  and any elements of attachments are not one of:
5934                  -  FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, and BACK_RIGHT, identifying that
5935                  specific buffer,
5936                  -  COLOR, which is treated as BACK_LEFT for a double-buffered context
5937                  and FRONT_LEFT for a single-buffered context,
5938                  -  DEPTH, identifying the depth buffer,
5939                  -  STENCIL, identifying the stencil buffer. */
5940                 gl.invalidateNamedFramebufferSubData(0, 1, &m_default_attachment_invalid, 0, 0, 1, 1);
5941
5942                 is_ok &= ExpectError(GL_INVALID_ENUM, "InvalidateNamedFramebufferSubData",
5943                                                          "the default framebuffer is affected, and any elements of attachments are not one of "
5944                                                          "FRONT_LEFT, FRONT_RIGHT, BACK_LEFT, BACK_RIGHT, COLOR, DEPTH, STENCIL.");
5945         }
5946         catch (...)
5947         {
5948                 is_ok   = false;
5949                 is_error = true;
5950         }
5951
5952         /* Cleanup. */
5953         Clean();
5954
5955         /* Result's setup. */
5956         if (is_ok)
5957         {
5958                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
5959         }
5960         else
5961         {
5962                 if (is_error)
5963                 {
5964                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
5965                 }
5966                 else
5967                 {
5968                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
5969                 }
5970         }
5971
5972         return STOP;
5973 }
5974
5975 /** Check Prepare test's GL objects.
5976  */
5977 void InvalidateDataAndSubDataErrorsTest::PrepareObjects()
5978 {
5979         /* Shortcut for GL functionality. */
5980         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
5981
5982         /* Valid attachments. */
5983         m_fbo_attachment_valid = GL_COLOR_ATTACHMENT0;
5984
5985         /* Valid objects. */
5986         gl.genFramebuffers(1, &m_fbo_valid);
5987         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
5988
5989         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
5990         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
5991
5992         gl.genRenderbuffers(1, &m_rbo);
5993         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
5994
5995         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo);
5996         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
5997
5998         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
5999         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
6000
6001         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, m_fbo_attachment_valid, GL_RENDERBUFFER, m_rbo);
6002         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
6003
6004         if (GL_FRAMEBUFFER_COMPLETE != gl.checkFramebufferStatus(GL_FRAMEBUFFER))
6005         {
6006                 throw 0;
6007         }
6008
6009         /* Invalid objects. */
6010         while (gl.isFramebuffer(++m_fbo_invalid))
6011                 ;
6012
6013         /* Invalid framebuffer object attachment. */
6014         while (true)
6015         {
6016                 if (GL_COLOR_ATTACHMENT0 < m_fbo_attachment_invalid)
6017                 {
6018                         /* If this unlikely happen this mean that we cannot create invalid attachment which is not DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT and
6019                          GL_COLOR_ATTACHMENTm where m IS any number (for m < MAX_COLOR_ATTACHMENTS attachments are valid, and for m >= MAX_COLOR_ATTACHMENTS is invalid, but
6020                          INVALID_OPERATION shall be generated instead of INVALID_ENUM. Such a situation may need change in the test or in the specification. */
6021                         throw 0;
6022                 }
6023
6024                 switch (++m_fbo_attachment_invalid)
6025                 {
6026                 case GL_DEPTH_ATTACHMENT:
6027                 case GL_STENCIL_ATTACHMENT:
6028                 case GL_DEPTH_STENCIL_ATTACHMENT:
6029                         continue;
6030                 };
6031
6032                 break;
6033         };
6034
6035         /* Invalid color attachment. */
6036         glw::GLint max_color_attachments = 8; /* Spec default. */
6037
6038         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments);
6039         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
6040
6041         m_color_attachment_invalid = GL_COLOR_ATTACHMENT0 + max_color_attachments;
6042
6043         /* Invalid default attachment. */
6044         while (true)
6045         {
6046                 switch (++m_default_attachment_invalid)
6047                 {
6048                 case GL_FRONT_LEFT:
6049                 case GL_FRONT_RIGHT:
6050                 case GL_BACK_LEFT:
6051                 case GL_BACK_RIGHT:
6052                 case GL_COLOR:
6053                 case GL_DEPTH:
6054                 case GL_STENCIL:
6055                         continue;
6056                 };
6057
6058                 break;
6059         }
6060 }
6061
6062 /** Check if error is equal to the expected, log if not.
6063  *
6064  *  @param [in] expected_error      Error to be expected.
6065  *  @param [in] function            Function name which is being tested (to be logged).
6066  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
6067  *
6068  *  @return True if there is no error, false otherwise.
6069  */
6070 bool InvalidateDataAndSubDataErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
6071                                                                                                          const glw::GLchar* conditions)
6072 {
6073         /* Shortcut for GL functionality. */
6074         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6075
6076         bool is_ok = true;
6077
6078         glw::GLenum error = GL_NO_ERROR;
6079
6080         if (expected_error != (error = gl.getError()))
6081         {
6082                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
6083                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
6084                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
6085
6086                 is_ok = false;
6087         }
6088
6089         /* Clean additional possible errors. */
6090         while (gl.getError())
6091                 ;
6092
6093         return is_ok;
6094 }
6095
6096 /** @brief Clean up GL state.
6097  */
6098 void InvalidateDataAndSubDataErrorsTest::Clean()
6099 {
6100         /* Shortcut for GL functionality. */
6101         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6102
6103         /* Release GL objects. */
6104         if (m_fbo_valid)
6105         {
6106                 gl.deleteFramebuffers(1, &m_fbo_valid);
6107                 m_fbo_valid = 0;
6108         }
6109
6110         if (m_rbo)
6111         {
6112                 gl.deleteRenderbuffers(1, &m_rbo);
6113
6114                 m_rbo = 0;
6115         }
6116
6117         /* Set initial values - all test shall have the same environment. */
6118         m_fbo_invalid                            = 0;
6119         m_fbo_attachment_valid           = 0;
6120         m_fbo_attachment_invalid         = 0;
6121         m_default_attachment_invalid = 0;
6122         m_color_attachment_invalid   = 0;
6123
6124         /* Errors clean up. */
6125         while (gl.getError())
6126                 ;
6127 }
6128
6129 /******************************** Clear Named Framebuffer Errors Test Implementation   ********************************/
6130
6131 /** @brief Clear Named Framebuffer Errors Test constructor.
6132  *
6133  *  @param [in] context     OpenGL context.
6134  */
6135 ClearNamedFramebufferErrorsTest::ClearNamedFramebufferErrorsTest(deqp::Context& context)
6136         : deqp::TestCase(context, "framebuffers_clear_errors", "Clear Named Framebuffer Errors Test")
6137         , m_fbo_valid(0)
6138         , m_rbo_color(0)
6139         , m_rbo_depth_stencil(0)
6140         , m_fbo_invalid(0)
6141 {
6142         /* Intentionally left blank. */
6143 }
6144
6145 /** @brief Iterate Clear Named Framebuffer Errors Test cases.
6146  *
6147  *  @return Iteration result.
6148  */
6149 tcu::TestNode::IterateResult ClearNamedFramebufferErrorsTest::iterate()
6150 {
6151         /* Shortcut for GL functionality. */
6152         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6153
6154         /* Get context setup. */
6155         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6156         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6157
6158         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6159         {
6160                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6161
6162                 return STOP;
6163         }
6164
6165         /* Running tests. */
6166         bool is_ok      = true;
6167         bool is_error = false;
6168
6169         try
6170         {
6171                 /* Prepare objects. */
6172                 PrepareObjects();
6173
6174                 glw::GLint   icolor[4] = {};
6175                 glw::GLuint  ucolor[4] = {};
6176                 glw::GLfloat fcolor[4] = {};
6177
6178                 /*  Check that INVALID_OPERATION is generated by ClearNamedFramebuffer* if
6179                  framebuffer is not zero or the name of an existing framebuffer object. */
6180                 gl.clearNamedFramebufferiv(m_fbo_invalid, GL_COLOR, 0, icolor);
6181
6182                 is_ok &= ExpectError(GL_INVALID_OPERATION, "ClearNamedFramebufferiv",
6183                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
6184
6185                 gl.clearNamedFramebufferuiv(m_fbo_invalid, GL_COLOR, 0, ucolor);
6186
6187                 is_ok &= ExpectError(GL_INVALID_OPERATION, "ClearNamedFramebufferuiv",
6188                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
6189
6190                 gl.clearNamedFramebufferfv(m_fbo_invalid, GL_COLOR, 0, fcolor);
6191
6192                 is_ok &= ExpectError(GL_INVALID_OPERATION, "ClearNamedFramebufferfv",
6193                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
6194
6195                 gl.clearNamedFramebufferfi(m_fbo_invalid, GL_DEPTH_STENCIL, 0, fcolor[0], icolor[0]);
6196
6197                 is_ok &= ExpectError(GL_INVALID_OPERATION, "ClearNamedFramebufferfi",
6198                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
6199
6200                 /*  Check that INVALID_ENUM is generated by ClearNamedFramebufferiv if buffer
6201                  is not COLOR or STENCIL. */
6202                 gl.clearNamedFramebufferiv(m_fbo_valid, GL_DEPTH, 0, icolor);
6203
6204                 is_ok &=
6205                         ExpectError(GL_INVALID_ENUM, "ClearNamedFramebufferiv", "buffer is not COLOR or STENCIL (it is DEPTH).");
6206
6207                 /*  Check that INVALID_ENUM is generated by ClearNamedFramebufferuiv if buffer
6208                  is not COLOR. */
6209                 gl.clearNamedFramebufferuiv(m_fbo_valid, GL_DEPTH, 0, ucolor);
6210
6211                 is_ok &= ExpectError(GL_INVALID_ENUM, "ClearNamedFramebufferuiv", "buffer is not COLOR (it is DEPTH).");
6212
6213                 /*  Check that INVALID_ENUM is generated by ClearNamedFramebufferfv buffer
6214                  is not COLOR or DEPTH. */
6215                 gl.clearNamedFramebufferfv(m_fbo_valid, GL_STENCIL, 0, fcolor);
6216
6217                 is_ok &=
6218                         ExpectError(GL_INVALID_ENUM, "ClearNamedFramebufferfv", "buffer is not COLOR or DEPTH (it is STENCIL).");
6219
6220                 /*  Check that INVALID_ENUM is generated by ClearNamedFramebufferfi if buffer
6221                  is not DEPTH_STENCIL. */
6222                 gl.clearNamedFramebufferfi(m_fbo_valid, GL_COLOR, 0, fcolor[0], icolor[0]);
6223
6224                 is_ok &= ExpectError(GL_INVALID_ENUM, "ClearNamedFramebufferfi", "buffer is not DEPTH_STENCIL.");
6225
6226                 /*  Check that INVALID_VALUE is generated by ClearNamedFramebuffer* if buffer is COLOR drawbuffer is
6227                  negative, or greater than the value of MAX_DRAW_BUFFERS minus one. */
6228                 gl.clearNamedFramebufferiv(m_fbo_valid, GL_COLOR, -1, icolor);
6229
6230                 is_ok &= ExpectError(
6231                         GL_INVALID_VALUE, "ClearNamedFramebufferiv",
6232                         "buffer is COLOR drawbuffer is negative, or greater than the value of MAX_DRAW_BUFFERS minus one.");
6233
6234                 gl.clearNamedFramebufferuiv(m_fbo_valid, GL_COLOR, -1, ucolor);
6235
6236                 is_ok &= ExpectError(
6237                         GL_INVALID_VALUE, "ClearNamedFramebufferuiv",
6238                         "buffer is COLOR drawbuffer is negative, or greater than the value of MAX_DRAW_BUFFERS minus one.");
6239
6240                 /*  Check that INVALID_VALUE is generated by ClearNamedFramebuffer* if buffer is DEPTH, STENCIL or
6241                  DEPTH_STENCIL and drawbuffer is not zero. */
6242
6243                 gl.clearNamedFramebufferiv(m_fbo_valid, GL_STENCIL, 1, icolor);
6244
6245                 is_ok &= ExpectError(GL_INVALID_VALUE, "ClearNamedFramebufferiv",
6246                                                          "buffer is DEPTH, STENCIL or DEPTH_STENCIL and drawbuffer is not zero.");
6247
6248                 gl.clearNamedFramebufferfv(m_fbo_valid, GL_DEPTH, 1, fcolor);
6249
6250                 is_ok &= ExpectError(GL_INVALID_VALUE, "ClearNamedFramebufferfv",
6251                                                          "buffer is DEPTH, STENCIL or DEPTH_STENCIL and drawbuffer is not zero.");
6252
6253                 gl.clearNamedFramebufferfi(m_fbo_valid, GL_DEPTH_STENCIL, 1, fcolor[0], icolor[0]);
6254
6255                 is_ok &= ExpectError(GL_INVALID_VALUE, "ClearNamedFramebufferfi",
6256                                                          "buffer is DEPTH, STENCIL or DEPTH_STENCIL and drawbuffer is not zero.");
6257         }
6258         catch (...)
6259         {
6260                 is_ok   = false;
6261                 is_error = true;
6262         }
6263
6264         /* Cleanup. */
6265         Clean();
6266
6267         /* Result's setup. */
6268         if (is_ok)
6269         {
6270                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6271         }
6272         else
6273         {
6274                 if (is_error)
6275                 {
6276                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6277                 }
6278                 else
6279                 {
6280                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6281                 }
6282         }
6283
6284         return STOP;
6285 }
6286
6287 /** Check Prepare test's GL objects.
6288  */
6289 void ClearNamedFramebufferErrorsTest::PrepareObjects()
6290 {
6291         /* Shortcut for GL functionality. */
6292         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6293
6294         /* Valid objects. */
6295         gl.genFramebuffers(1, &m_fbo_valid);
6296         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
6297
6298         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
6299         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
6300
6301         gl.genRenderbuffers(1, &m_rbo_color);
6302         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
6303
6304         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_color);
6305         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
6306
6307         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, 1, 1);
6308         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
6309
6310         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color);
6311         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
6312
6313         gl.genRenderbuffers(1, &m_rbo_depth_stencil);
6314         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
6315
6316         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_depth_stencil);
6317         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
6318
6319         gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1, 1);
6320         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
6321
6322         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil);
6323         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
6324
6325         /* Invalid objects. */
6326         while (gl.isFramebuffer(++m_fbo_invalid))
6327                 ;
6328 }
6329
6330 /** Check if error is equal to the expected, log if not.
6331  *
6332  *  @param [in] expected_error      Error to be expected.
6333  *  @param [in] function            Function name which is being tested (to be logged).
6334  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
6335  *
6336  *  @return True if there is no error, false otherwise.
6337  */
6338 bool ClearNamedFramebufferErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
6339                                                                                                   const glw::GLchar* conditions)
6340 {
6341         /* Shortcut for GL functionality. */
6342         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6343
6344         bool is_ok = true;
6345
6346         glw::GLenum error = GL_NO_ERROR;
6347
6348         if (expected_error != (error = gl.getError()))
6349         {
6350                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
6351                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
6352                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
6353
6354                 is_ok = false;
6355         }
6356
6357         /* Clean additional possible errors. */
6358         while (gl.getError())
6359                 ;
6360
6361         return is_ok;
6362 }
6363
6364 /** @brief Clean up GL state.
6365  */
6366 void ClearNamedFramebufferErrorsTest::Clean()
6367 {
6368         /* Shortcut for GL functionality. */
6369         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6370
6371         /* Release GL objects. */
6372         if (m_fbo_valid)
6373         {
6374                 gl.deleteFramebuffers(1, &m_fbo_valid);
6375                 m_fbo_valid = 0;
6376         }
6377
6378         if (m_rbo_color)
6379         {
6380                 gl.deleteRenderbuffers(1, &m_rbo_color);
6381                 m_rbo_color = 0;
6382         }
6383
6384         if (m_rbo_depth_stencil)
6385         {
6386                 gl.deleteRenderbuffers(1, &m_rbo_depth_stencil);
6387                 m_rbo_depth_stencil = 0;
6388         }
6389
6390         /* Set initial values - all test shall have the same environment. */
6391         m_fbo_invalid = 0;
6392
6393         /* Errors clean up. */
6394         while (gl.getError())
6395                 ;
6396 }
6397
6398 /******************************** Check Status Errors Test Implementation   ********************************/
6399
6400 /** @brief Clear Named Framebuffer Errors Test constructor.
6401  *
6402  *  @param [in] context     OpenGL context.
6403  */
6404 CheckStatusErrorsTest::CheckStatusErrorsTest(deqp::Context& context)
6405         : deqp::TestCase(context, "framebuffers_check_status_errors", "Check Status Errors Test")
6406         , m_fbo_valid(0)
6407         , m_fbo_invalid(0)
6408         , m_target_invalid(0)
6409 {
6410         /* Intentionally left blank. */
6411 }
6412
6413 /** @brief Iterate Clear Named Framebuffer Errors Test cases.
6414  *
6415  *  @return Iteration result.
6416  */
6417 tcu::TestNode::IterateResult CheckStatusErrorsTest::iterate()
6418 {
6419         /* Shortcut for GL functionality. */
6420         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6421
6422         /* Get context setup. */
6423         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6424         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6425
6426         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6427         {
6428                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6429
6430                 return STOP;
6431         }
6432
6433         /* Running tests. */
6434         bool is_ok      = true;
6435         bool is_error = false;
6436
6437         try
6438         {
6439                 /* Prepare objects. */
6440                 PrepareObjects();
6441
6442                 /*  Check that INVALID_ENUM is generated by CheckNamedFramebufferStatus if
6443                  target is not DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER. */
6444                 gl.checkNamedFramebufferStatus(m_fbo_valid, m_target_invalid);
6445
6446                 is_ok &= ExpectError(GL_INVALID_ENUM, "CheckNamedFramebufferStatus",
6447                                                          "target is not DRAW_FRAMEBUFFER, READ_FRAMEBUFFER or FRAMEBUFFER.");
6448
6449                 /*  Check that INVALID_OPERATION is generated by CheckNamedFramebufferStatus
6450                  if framebuffer is not zero or the name of an existing framebuffer
6451                  object. */
6452                 gl.checkNamedFramebufferStatus(m_fbo_invalid, GL_FRAMEBUFFER);
6453
6454                 is_ok &= ExpectError(GL_INVALID_OPERATION, "CheckNamedFramebufferStatus",
6455                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
6456         }
6457         catch (...)
6458         {
6459                 is_ok   = false;
6460                 is_error = true;
6461         }
6462
6463         /* Cleanup. */
6464         Clean();
6465
6466         /* Result's setup. */
6467         if (is_ok)
6468         {
6469                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6470         }
6471         else
6472         {
6473                 if (is_error)
6474                 {
6475                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6476                 }
6477                 else
6478                 {
6479                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6480                 }
6481         }
6482
6483         return STOP;
6484 }
6485
6486 /** Check Prepare test's GL objects.
6487  */
6488 void CheckStatusErrorsTest::PrepareObjects()
6489 {
6490         /* Shortcut for GL functionality. */
6491         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6492
6493         /* Valid objects. */
6494         gl.genFramebuffers(1, &m_fbo_valid);
6495         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
6496
6497         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
6498         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
6499
6500         /* Invalid target. */
6501         bool is_target = true;
6502
6503         while (is_target)
6504         {
6505                 is_target = false;
6506
6507                 ++m_target_invalid;
6508
6509                 if (GL_FRAMEBUFFER == m_target_invalid)
6510                 {
6511                         is_target = true;
6512                 }
6513
6514                 if (GL_READ_FRAMEBUFFER == m_target_invalid)
6515                 {
6516                         is_target = true;
6517                 }
6518
6519                 if (GL_DRAW_FRAMEBUFFER == m_target_invalid)
6520                 {
6521                         is_target = true;
6522                 }
6523         }
6524         /* Invalid objects. */
6525         while (gl.isFramebuffer(++m_fbo_invalid))
6526                 ;
6527 }
6528
6529 /** Check if error is equal to the expected, log if not.
6530  *
6531  *  @param [in] expected_error      Error to be expected.
6532  *  @param [in] function            Function name which is being tested (to be logged).
6533  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
6534  *
6535  *  @return True if there is no error, false otherwise.
6536  */
6537 bool CheckStatusErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
6538                                                                                 const glw::GLchar* conditions)
6539 {
6540         /* Shortcut for GL functionality. */
6541         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6542
6543         bool is_ok = true;
6544
6545         glw::GLenum error = GL_NO_ERROR;
6546
6547         if (expected_error != (error = gl.getError()))
6548         {
6549                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
6550                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
6551                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
6552
6553                 is_ok = false;
6554         }
6555
6556         /* Clean additional possible errors. */
6557         while (gl.getError())
6558                 ;
6559
6560         return is_ok;
6561 }
6562
6563 /** @brief Clean up GL state.
6564  */
6565 void CheckStatusErrorsTest::Clean()
6566 {
6567         /* Shortcut for GL functionality. */
6568         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6569
6570         /* Release GL objects. */
6571         if (m_fbo_valid)
6572         {
6573                 gl.deleteFramebuffers(1, &m_fbo_valid);
6574                 m_fbo_valid = 0;
6575         }
6576
6577         /* Set initial values - all test shall have the same environment. */
6578         m_fbo_invalid   = 0;
6579         m_target_invalid = 0;
6580
6581         /* Errors clean up. */
6582         while (gl.getError())
6583                 ;
6584 }
6585
6586 /******************************** Get Parameter Errors Test Implementation   ********************************/
6587
6588 /** @brief Get Parameter Errors Test constructor.
6589  *
6590  *  @param [in] context     OpenGL context.
6591  */
6592 GetParameterErrorsTest::GetParameterErrorsTest(deqp::Context& context)
6593         : deqp::TestCase(context, "framebuffers_get_parameter_errors", "Get Parameter Errors Test")
6594         , m_fbo_valid(0)
6595         , m_fbo_invalid(0)
6596         , m_parameter_invalid(0)
6597 {
6598         /* Intentionally left blank. */
6599 }
6600
6601 /** @brief Iterate Get Parameter Errors Test cases.
6602  *
6603  *  @return Iteration result.
6604  */
6605 tcu::TestNode::IterateResult GetParameterErrorsTest::iterate()
6606 {
6607         /* Shortcut for GL functionality. */
6608         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6609
6610         /* Get context setup. */
6611         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6612         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6613
6614         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6615         {
6616                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6617
6618                 return STOP;
6619         }
6620
6621         /* Running tests. */
6622         bool is_ok      = true;
6623         bool is_error = false;
6624
6625         try
6626         {
6627                 /* Prepare objects. */
6628                 PrepareObjects();
6629
6630                 glw::GLint return_values_dummy_storage[4];
6631
6632                 /*  Check that INVALID_OPERATION is generated by
6633                  GetNamedFramebufferParameteriv if framebuffer is not zero or the name of
6634                  an existing framebuffer object. */
6635                 gl.getNamedFramebufferParameteriv(m_fbo_invalid, GL_SAMPLES, return_values_dummy_storage);
6636
6637                 is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferParameteriv",
6638                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
6639
6640                 /*  Check that INVALID_ENUM is generated by GetNamedFramebufferParameteriv
6641                  if pname is not one of the accepted parameter names. */
6642                 gl.getNamedFramebufferParameteriv(m_fbo_valid, m_parameter_invalid, return_values_dummy_storage);
6643
6644                 is_ok &= ExpectError(GL_INVALID_ENUM, "GetNamedFramebufferParameteriv",
6645                                                          "pname is not one of the accepted parameter names.");
6646
6647                 /*  Check that INVALID_OPERATION is generated if a default framebuffer is
6648                  queried, and pname is not one of DOUBLEBUFFER,
6649                  IMPLEMENTATION_COLOR_READ_FORMAT, IMPLEMENTATION_COLOR_READ_TYPE,
6650                  SAMPLES, SAMPLE_BUFFERS or STEREO. */
6651                 gl.getNamedFramebufferParameteriv(0, GL_FRAMEBUFFER_DEFAULT_WIDTH, return_values_dummy_storage);
6652
6653                 is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferParameteriv",
6654                                                          "a default framebuffer is queried, and pname is not one of DOUBLEBUFFER, "
6655                                                          "IMPLEMENTATION_COLOR_READ_FORMAT, IMPLEMENTATION_COLOR_READ_TYPE, SAMPLES, "
6656                                                          "SAMPLE_BUFFERS or STEREO.");
6657         }
6658         catch (...)
6659         {
6660                 is_ok   = false;
6661                 is_error = true;
6662         }
6663
6664         /* Cleanup. */
6665         Clean();
6666
6667         /* Result's setup. */
6668         if (is_ok)
6669         {
6670                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6671         }
6672         else
6673         {
6674                 if (is_error)
6675                 {
6676                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6677                 }
6678                 else
6679                 {
6680                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6681                 }
6682         }
6683
6684         return STOP;
6685 }
6686
6687 /** Check Prepare test's GL objects.
6688  */
6689 void GetParameterErrorsTest::PrepareObjects()
6690 {
6691         /* Shortcut for GL functionality. */
6692         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6693
6694         /* Valid objects. */
6695         gl.genFramebuffers(1, &m_fbo_valid);
6696         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
6697
6698         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
6699         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
6700
6701         /* Invalid target. */
6702         bool is_parameter = true;
6703
6704         while (is_parameter)
6705         {
6706                 is_parameter = false;
6707
6708                 ++m_parameter_invalid;
6709
6710                 static const glw::GLenum valid_parameters[] = { GL_FRAMEBUFFER_DEFAULT_WIDTH,
6711                                                                                                                 GL_FRAMEBUFFER_DEFAULT_HEIGHT,
6712                                                                                                                 GL_FRAMEBUFFER_DEFAULT_LAYERS,
6713                                                                                                                 GL_FRAMEBUFFER_DEFAULT_SAMPLES,
6714                                                                                                                 GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS,
6715                                                                                                                 GL_DOUBLEBUFFER,
6716                                                                                                                 GL_IMPLEMENTATION_COLOR_READ_FORMAT,
6717                                                                                                                 GL_IMPLEMENTATION_COLOR_READ_TYPE,
6718                                                                                                                 GL_SAMPLES,
6719                                                                                                                 GL_SAMPLE_BUFFERS,
6720                                                                                                                 GL_STEREO };
6721
6722                 static const glw::GLuint valid_parameters_count = sizeof(valid_parameters) / sizeof(valid_parameters[0]);
6723
6724                 for (glw::GLuint i = 0; i < valid_parameters_count; ++i)
6725                 {
6726                         if (valid_parameters[i] == m_parameter_invalid)
6727                         {
6728                                 is_parameter = true;
6729                         }
6730                 }
6731         }
6732
6733         /* Invalid objects. */
6734         while (gl.isFramebuffer(++m_fbo_invalid))
6735                 ;
6736 }
6737
6738 /** Check if error is equal to the expected, log if not.
6739  *
6740  *  @param [in] expected_error      Error to be expected.
6741  *  @param [in] function            Function name which is being tested (to be logged).
6742  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
6743  *
6744  *  @return True if there is no error, false otherwise.
6745  */
6746 bool GetParameterErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
6747                                                                                  const glw::GLchar* conditions)
6748 {
6749         /* Shortcut for GL functionality. */
6750         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6751
6752         bool is_ok = true;
6753
6754         glw::GLenum error = GL_NO_ERROR;
6755
6756         if (expected_error != (error = gl.getError()))
6757         {
6758                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
6759                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
6760                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
6761
6762                 is_ok = false;
6763         }
6764
6765         /* Clean additional possible errors. */
6766         while (gl.getError())
6767                 ;
6768
6769         return is_ok;
6770 }
6771
6772 /** @brief Clean up GL state.
6773  */
6774 void GetParameterErrorsTest::Clean()
6775 {
6776         /* Shortcut for GL functionality. */
6777         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6778
6779         /* Release GL objects. */
6780         if (m_fbo_valid)
6781         {
6782                 gl.deleteFramebuffers(1, &m_fbo_valid);
6783                 m_fbo_valid = 0;
6784         }
6785
6786         /* Set initial values - all test shall have the same environment. */
6787         m_fbo_invalid           = 0;
6788         m_parameter_invalid = 0;
6789
6790         /* Errors clean up. */
6791         while (gl.getError())
6792                 ;
6793 }
6794
6795 /******************************** Get Attachment Parameter Errors Test Implementation   ********************************/
6796
6797 /** @brief Get Attachment Parameter Errors Test constructor.
6798  *
6799  *  @param [in] context     OpenGL context.
6800  */
6801 GetAttachmentParameterErrorsTest::GetAttachmentParameterErrorsTest(deqp::Context& context)
6802         : deqp::TestCase(context, "framebuffers_get_attachment_parameter_errors", "Get Attachment Parameter Errors Test")
6803         , m_fbo_valid(0)
6804         , m_rbo_color(0)
6805         , m_rbo_depth_stencil(0)
6806         , m_fbo_invalid(0)
6807         , m_parameter_invalid(0)
6808         , m_attachment_invalid(0)
6809         , m_default_attachment_invalid(0)
6810         , m_max_color_attachments(8) /* Spec default. */
6811 {
6812         /* Intentionally left blank. */
6813 }
6814
6815 /** @brief Iterate Get Attachment Parameter Errors Test cases.
6816  *
6817  *  @return Iteration result.
6818  */
6819 tcu::TestNode::IterateResult GetAttachmentParameterErrorsTest::iterate()
6820 {
6821         /* Shortcut for GL functionality. */
6822         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6823
6824         /* Get context setup. */
6825         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
6826         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
6827
6828         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
6829         {
6830                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
6831
6832                 return STOP;
6833         }
6834
6835         /* Running tests. */
6836         bool is_ok      = true;
6837         bool is_error = false;
6838
6839         try
6840         {
6841                 /* Prepare objects. */
6842                 PrepareObjects();
6843
6844                 glw::GLint return_values_dummy_storage[4];
6845
6846                 /*  Check that GL_INVALID_OPERATION is generated by
6847                  GetNamedFramebufferAttachmentParameteriv if framebuffer is not zero or
6848                  the name of an existing framebuffer object. */
6849                 gl.getNamedFramebufferAttachmentParameteriv(
6850                         m_fbo_invalid, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, return_values_dummy_storage);
6851
6852                 is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
6853                                                          "framebuffer is not zero or the name of an existing framebuffer object.");
6854
6855                 /*  Check that INVALID_ENUM is generated by
6856                  GetNamedFramebufferAttachmentParameteriv if pname is not valid for the
6857                  value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, as described above. */
6858                 gl.getNamedFramebufferAttachmentParameteriv(
6859                         m_fbo_valid, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, return_values_dummy_storage);
6860
6861                 is_ok &= ExpectError(
6862                         GL_INVALID_ENUM, "GetNamedFramebufferAttachmentParameteriv",
6863                         "pname is not valid for the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, as described above.");
6864
6865                 /*  Check that INVALID_ENUM error is generated if a framebuffer object is queried, attachment
6866                  is not one of the attachments in table 9.2 (COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT), and attachment is not
6867                  COLOR_ATTACHMENTm where m is greater than or equal to the value of MAX_COLOR_ATTACHMENTS. */
6868                 gl.getNamedFramebufferAttachmentParameteriv(
6869                         m_fbo_valid, m_attachment_invalid, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, return_values_dummy_storage);
6870
6871                 is_ok &= ExpectError(
6872                         GL_INVALID_ENUM, "GetNamedFramebufferAttachmentParameteriv",
6873                         "attachment is not one of the accepted framebuffer attachment points, as described in specification.");
6874
6875                 /*  Check that INVALID_OPERATION is generated by
6876                  GetNamedFramebufferAttachmentParameteriv if the value of
6877                  FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE and pname is not
6878                  FRAMEBUFFER_ATTACHMENT_OBJECT_NAME or
6879                  FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE. */
6880                 gl.getNamedFramebufferAttachmentParameteriv(
6881                         m_fbo_valid, GL_COLOR_ATTACHMENT1, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, return_values_dummy_storage);
6882
6883                 is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
6884                                                          "the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE and pname is not "
6885                                                          "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME or FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE.");
6886
6887                 /*  Check that INVALID_OPERATION is generated by
6888                  GetNamedFramebufferAttachmentParameteriv if attachment is
6889                  DEPTH_STENCIL_ATTACHMENT and pname is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE. */
6890                 gl.getNamedFramebufferAttachmentParameteriv(m_fbo_valid, GL_DEPTH_STENCIL_ATTACHMENT,
6891                                                                                                         GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
6892                                                                                                         return_values_dummy_storage);
6893
6894                 is_ok &=
6895                         ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
6896                                                 "attachment is DEPTH_STENCIL_ATTACHMENT and pname is FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE.");
6897
6898                 /*  Check that an INVALID_ENUM error is generated if the default framebuffer is
6899                  queried and attachment is not one the values FRONT, FRONT_LEFT, FRONT_RIGHT,
6900                  BACK, BACK_LEFT, BACK_RIGHT, DEPTH, STENCIL. */
6901                 gl.getNamedFramebufferAttachmentParameteriv(
6902                         0, m_default_attachment_invalid, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, return_values_dummy_storage);
6903
6904                 is_ok &= ExpectError(GL_INVALID_ENUM, "GetNamedFramebufferAttachmentParameteriv",
6905                                                          "the default framebuffer is queried and attachment is not one the values FRONT, "
6906                                                          "FRONT_LEFT, FRONT_RIGHT, BACK, BACK_LEFT, BACK_RIGHT, DEPTH, STENCIL.");
6907
6908                 /*  Check that an INVALID_OPERATION error is generated if a framebuffer object is
6909                  bound to target and attachment is COLOR_ATTACHMENTm where m is greater than or
6910                  equal to the value of MAX_COLOR_ATTACHMENTS. */
6911                 gl.getNamedFramebufferAttachmentParameteriv(m_fbo_valid, GL_COLOR_ATTACHMENT0 + m_max_color_attachments,
6912                                                                                                         GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
6913                                                                                                         return_values_dummy_storage);
6914
6915                 is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
6916                                                          "a framebuffer object is bound to target and attachment is COLOR_ATTACHMENTm where m is "
6917                                                          "equal to the value of MAX_COLOR_ATTACHMENTS.");
6918
6919                 gl.getNamedFramebufferAttachmentParameteriv(m_fbo_valid, GL_COLOR_ATTACHMENT0 + m_max_color_attachments + 1,
6920                                                                                                         GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
6921                                                                                                         return_values_dummy_storage);
6922
6923                 is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedFramebufferAttachmentParameteriv",
6924                                                          "a framebuffer object is bound to target and attachment is COLOR_ATTACHMENTm where m is "
6925                                                          "greater than the value of MAX_COLOR_ATTACHMENTS.");
6926         }
6927         catch (...)
6928         {
6929                 is_ok   = false;
6930                 is_error = true;
6931         }
6932
6933         /* Cleanup. */
6934         Clean();
6935
6936         /* Result's setup. */
6937         if (is_ok)
6938         {
6939                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
6940         }
6941         else
6942         {
6943                 if (is_error)
6944                 {
6945                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
6946                 }
6947                 else
6948                 {
6949                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
6950                 }
6951         }
6952
6953         return STOP;
6954 }
6955
6956 /** Check Prepare test's GL objects.
6957  */
6958 void GetAttachmentParameterErrorsTest::PrepareObjects()
6959 {
6960         /* Shortcut for GL functionality. */
6961         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
6962
6963         /* Valid objects. */
6964         gl.genFramebuffers(1, &m_fbo_valid);
6965         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
6966
6967         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_valid);
6968         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
6969
6970         gl.genRenderbuffers(1, &m_rbo_color);
6971         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
6972
6973         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_color);
6974         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
6975
6976         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R8, 1, 1);
6977         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
6978
6979         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color);
6980         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
6981
6982         gl.genRenderbuffers(1, &m_rbo_depth_stencil);
6983         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
6984
6985         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_depth_stencil);
6986         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
6987
6988         gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1, 1);
6989         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
6990
6991         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil);
6992         GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferRenderbuffer has failed");
6993
6994         /* Max color attachments. */
6995         gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &m_max_color_attachments);
6996         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv has failed");
6997
6998         /* Invalid attachment. */
6999         bool is_attachment = true;
7000
7001         while (is_attachment)
7002         {
7003                 is_attachment = false;
7004
7005                 if ((GL_DEPTH_ATTACHMENT == m_attachment_invalid) || (GL_STENCIL_ATTACHMENT == m_attachment_invalid) ||
7006                         (GL_DEPTH_STENCIL_ATTACHMENT == m_attachment_invalid))
7007                 {
7008                         ++m_attachment_invalid;
7009                         is_attachment = true;
7010                 }
7011
7012                 if (GL_COLOR_ATTACHMENT0 < m_attachment_invalid)
7013                 {
7014                         /* If this unlikely happen this mean that we cannot create invalid attachment which is not DEPTH_ATTACHMENT, STENCIL_ATTACHMENT, DEPTH_STENCIL_ATTACHMENT and
7015                          GL_COLOR_ATTACHMENTm where m IS any number (for m < MAX_COLOR_ATTACHMENTS attachments are valid, and for m >= MAX_COLOR_ATTACHMENTS is invalid, but
7016                          INVALID_OPERATION shall be generated instead of INVALID_ENUM. Such a situation may need change in the test or in the specification. */
7017                         throw 0;
7018                 }
7019         }
7020
7021         /* Invalid default framebuffer attachment. */
7022         bool is_default_attachment = true;
7023
7024         while (is_default_attachment)
7025         {
7026                 is_default_attachment = false;
7027
7028                 static const glw::GLenum valid_values[] = { GL_FRONT,    GL_FRONT_LEFT, GL_FRONT_RIGHT, GL_BACK,
7029                                                                                                         GL_BACK_LEFT, GL_BACK_RIGHT, GL_DEPTH,           GL_STENCIL };
7030
7031                 static const glw::GLuint valid_values_count = sizeof(valid_values) / sizeof(valid_values[0]);
7032
7033                 for (glw::GLuint i = 0; i < valid_values_count; ++i)
7034                 {
7035                         if (valid_values[i] == m_default_attachment_invalid)
7036                         {
7037                                 m_default_attachment_invalid++;
7038                                 is_default_attachment = true;
7039                                 break;
7040                         }
7041                 }
7042         }
7043
7044         /* Invalid parameter. */
7045         bool is_parameter = true;
7046
7047         while (is_parameter)
7048         {
7049                 is_parameter = false;
7050
7051                 ++m_parameter_invalid;
7052
7053                 static const glw::GLenum valid_parameters[] = { GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
7054                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
7055                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE,
7056                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
7057                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE,
7058                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
7059                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE,
7060                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING,
7061                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
7062                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
7063                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
7064                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_LAYERED,
7065                                                                                                                 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER };
7066
7067                 static const glw::GLuint valid_parameters_count = sizeof(valid_parameters) / sizeof(valid_parameters[0]);
7068
7069                 for (glw::GLuint i = 0; i < valid_parameters_count; ++i)
7070                 {
7071                         if (valid_parameters[i] == m_parameter_invalid)
7072                         {
7073                                 is_parameter = true;
7074                         }
7075                 }
7076         }
7077
7078         /* Invalid objects. */
7079         while (gl.isFramebuffer(++m_fbo_invalid))
7080                 ;
7081 }
7082
7083 /** Check if error is equal to the expected, log if not.
7084  *
7085  *  @param [in] expected_error      Error to be expected.
7086  *  @param [in] function            Function name which is being tested (to be logged).
7087  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
7088  *
7089  *  @return True if there is no error, false otherwise.
7090  */
7091 bool GetAttachmentParameterErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
7092                                                                                                    const glw::GLchar* conditions)
7093 {
7094         /* Shortcut for GL functionality. */
7095         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7096
7097         bool is_ok = true;
7098
7099         glw::GLenum error = GL_NO_ERROR;
7100
7101         if (expected_error != (error = gl.getError()))
7102         {
7103                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
7104                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
7105                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
7106
7107                 is_ok = false;
7108         }
7109
7110         /* Clean additional possible errors. */
7111         while (gl.getError())
7112                 ;
7113
7114         return is_ok;
7115 }
7116
7117 /** @brief Clean up GL state.
7118  */
7119 void GetAttachmentParameterErrorsTest::Clean()
7120 {
7121         /* Shortcut for GL functionality. */
7122         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7123
7124         /* Release GL objects. */
7125         if (m_fbo_valid)
7126         {
7127                 gl.deleteFramebuffers(1, &m_fbo_valid);
7128                 m_fbo_valid = 0;
7129         }
7130
7131         if (m_rbo_color)
7132         {
7133                 gl.deleteRenderbuffers(1, &m_rbo_color);
7134                 m_rbo_color = 0;
7135         }
7136
7137         if (m_rbo_depth_stencil)
7138         {
7139                 gl.deleteRenderbuffers(1, &m_rbo_depth_stencil);
7140                 m_rbo_depth_stencil = 0;
7141         }
7142
7143         /* Set initial values - all test shall have the same environment. */
7144         m_fbo_invalid                            = 0;
7145         m_parameter_invalid                      = 0;
7146         m_attachment_invalid             = 0;
7147         m_default_attachment_invalid = 0;
7148         m_max_color_attachments          = 8;
7149
7150         /* Errors clean up. */
7151         while (gl.getError())
7152                 ;
7153 }
7154
7155 /******************************** Functional Test Implementation   ********************************/
7156
7157 /** @brief Get Attachment Parameter Errors Test constructor.
7158  *
7159  *  @param [in] context     OpenGL context.
7160  */
7161 FunctionalTest::FunctionalTest(deqp::Context& context)
7162         : deqp::TestCase(context, "framebuffers_renderbuffers_functional", "Functional Test")
7163         , m_fbo_1st(0)
7164         , m_fbo_2nd(0)
7165         , m_rbo_color(0)
7166         , m_rbo_depth_stencil(0)
7167         , m_to_color(0)
7168         , m_po(0)
7169         , m_vao_stencil_pass_quad(0)
7170         , m_vao_depth_pass_quad(0)
7171         , m_vao_color_pass_quad(0)
7172         , m_bo_stencil_pass_quad(0)
7173         , m_bo_depth_pass_quad(0)
7174         , m_bo_color_pass_quad(0)
7175 {
7176         /* Intentionally left blank. */
7177 }
7178
7179 /** @brief Iterate Get Attachment Parameter Errors Test cases.
7180  *
7181  *  @return Iteration result.
7182  */
7183 tcu::TestNode::IterateResult FunctionalTest::iterate()
7184 {
7185         /* Get context setup. */
7186         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7187         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7188
7189         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7190         {
7191                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7192
7193                 return STOP;
7194         }
7195
7196         /* Running tests. */
7197         bool is_ok      = true;
7198         bool is_error = false;
7199
7200         try
7201         {
7202                 /* Test. */
7203                 is_ok &= PrepareFirstFramebuffer();
7204                 is_ok &= PrepareSecondFramebuffer();
7205                 is_ok &= ClearFramebuffers();
7206                 PrepareProgram();
7207                 PrepareBuffersAndVertexArrays();
7208                 is_ok &= DrawAndBlit();
7209                 is_ok &= CheckSecondFramebufferContent();
7210         }
7211         catch (...)
7212         {
7213                 is_ok   = false;
7214                 is_error = true;
7215         }
7216
7217         /* Cleanup. */
7218         Clean();
7219
7220         /* Result's setup. */
7221         if (is_ok)
7222         {
7223                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7224         }
7225         else
7226         {
7227                 if (is_error)
7228                 {
7229                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
7230                 }
7231                 else
7232                 {
7233                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
7234                 }
7235         }
7236
7237         return STOP;
7238 }
7239
7240 /** Prepare first framebuffer.
7241  *
7242  *  @return True if there is no error, false otherwise.
7243  */
7244 bool FunctionalTest::PrepareFirstFramebuffer()
7245 {
7246         /* Shortcut for GL functionality. */
7247         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7248
7249         /* Failure of this part shall result in test failure (it is DSA functionality failure). */
7250         try
7251         {
7252                 gl.createFramebuffers(1, &m_fbo_1st);
7253                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");
7254
7255                 gl.createRenderbuffers(1, &m_rbo_color);
7256                 gl.createRenderbuffers(1, &m_rbo_depth_stencil);
7257                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateRenderbuffers has failed");
7258
7259                 gl.namedRenderbufferStorage(m_rbo_color, GL_R8, 8, 8);
7260                 gl.namedRenderbufferStorage(m_rbo_depth_stencil, GL_DEPTH24_STENCIL8, 8, 8);
7261                 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedRenderbufferStorage has failed");
7262
7263                 gl.namedFramebufferRenderbuffer(m_fbo_1st, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo_color);
7264                 gl.namedFramebufferRenderbuffer(m_fbo_1st, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo_depth_stencil);
7265                 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedFramebufferRenderbuffer has failed");
7266
7267                 if (GL_FRAMEBUFFER_COMPLETE != gl.checkNamedFramebufferStatus(m_fbo_1st, GL_FRAMEBUFFER))
7268                 {
7269                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "CheckNamedFramebufferStatus is incomplete."
7270                                                                                                 << tcu::TestLog::EndMessage;
7271
7272                         throw 0;
7273                 }
7274         }
7275         catch (...)
7276         {
7277                 return false;
7278         }
7279
7280         return true;
7281 }
7282
7283 /** Prepare second framebuffer.
7284  *
7285  *  @return True if there is no error, false otherwise.
7286  */
7287 bool FunctionalTest::PrepareSecondFramebuffer()
7288 {
7289         /* Shortcut for GL functionality. */
7290         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7291
7292         /* Failure of this part shall result in test internal error (it does not test the DSA functionality). */
7293         gl.genTextures(1, &m_to_color);
7294         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures has failed");
7295
7296         gl.bindTexture(GL_TEXTURE_2D, m_to_color);
7297         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture has failed");
7298
7299         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_R8, 4, 3);
7300         GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D has failed");
7301
7302         /* Failure of this part shall result in test failure (it is DSA functionality failure). */
7303         try
7304         {
7305                 gl.createFramebuffers(1, &m_fbo_2nd);
7306                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateFramebuffers has failed");
7307
7308                 gl.namedFramebufferTexture(m_fbo_2nd, GL_COLOR_ATTACHMENT0, m_to_color, 0);
7309                 GLU_EXPECT_NO_ERROR(gl.getError(), "glNamedFramebufferTexture has failed");
7310
7311                 if (GL_FRAMEBUFFER_COMPLETE != gl.checkNamedFramebufferStatus(m_fbo_2nd, GL_FRAMEBUFFER))
7312                 {
7313                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "CheckNamedFramebufferStatus is incomplete."
7314                                                                                                 << tcu::TestLog::EndMessage;
7315
7316                         throw 0;
7317                 }
7318         }
7319         catch (...)
7320         {
7321                 return false;
7322         }
7323
7324         return true;
7325 }
7326
7327 /** Clear framebuffers.
7328  *
7329  *  @return True if there is no error, false otherwise.
7330  */
7331 bool FunctionalTest::ClearFramebuffers()
7332 {
7333         /* Shortcut for GL functionality. */
7334         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7335
7336         /* Failure of this part shall result in test failure (it is DSA functionality failure). */
7337         try
7338         {
7339                 glw::GLfloat color_value[] = { 0.f, 0.f, 0.f, 0.f };
7340                 glw::GLfloat depth_value   = 0.f;
7341                 glw::GLint   stencil_value = 0;
7342
7343                 /* 1st framebuffer. */
7344                 gl.clearNamedFramebufferfv(m_fbo_1st, GL_COLOR, 0, color_value);
7345                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedFramebufferfv has failed");
7346
7347                 gl.clearNamedFramebufferfi(m_fbo_1st, GL_DEPTH_STENCIL, 0, depth_value, stencil_value);
7348                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedFramebufferfi has failed");
7349
7350                 /* 2nd framebuffer. */
7351                 gl.clearNamedFramebufferfv(m_fbo_1st, GL_COLOR, 0, color_value);
7352                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearNamedFramebufferfv has failed");
7353         }
7354         catch (...)
7355         {
7356                 return false;
7357         }
7358
7359         return true;
7360 }
7361
7362 /** Prepare test's GLSL program.
7363  */
7364 void FunctionalTest::PrepareProgram()
7365 {
7366         /* Shortcut for GL functionality */
7367         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7368
7369         struct Shader
7370         {
7371                 glw::GLchar const* const source;
7372                 glw::GLenum const                type;
7373                 glw::GLuint                              id;
7374         } shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
7375
7376         glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
7377
7378         try
7379         {
7380                 /* Create program. */
7381                 m_po = gl.createProgram();
7382                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
7383
7384                 /* Shader compilation. */
7385                 for (glw::GLuint i = 0; i < shader_count; ++i)
7386                 {
7387                         if (DE_NULL != shader[i].source)
7388                         {
7389                                 shader[i].id = gl.createShader(shader[i].type);
7390
7391                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
7392
7393                                 gl.attachShader(m_po, shader[i].id);
7394
7395                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
7396
7397                                 gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
7398
7399                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
7400
7401                                 gl.compileShader(shader[i].id);
7402
7403                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
7404
7405                                 glw::GLint status = GL_FALSE;
7406
7407                                 gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
7408                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
7409
7410                                 if (GL_FALSE == status)
7411                                 {
7412                                         glw::GLint log_size = 0;
7413                                         gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
7414                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
7415
7416                                         glw::GLchar* log_text = new glw::GLchar[log_size];
7417
7418                                         gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
7419
7420                                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
7421                                                                                                                 << "Shader type: " << glu::getShaderTypeStr(shader[i].type)
7422                                                                                                                 << "\n"
7423                                                                                                                 << "Shader compilation error log:\n"
7424                                                                                                                 << log_text << "\n"
7425                                                                                                                 << "Shader source code:\n"
7426                                                                                                                 << shader[i].source << "\n"
7427                                                                                                                 << tcu::TestLog::EndMessage;
7428
7429                                         delete[] log_text;
7430
7431                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
7432
7433                                         throw 0;
7434                                 }
7435                         }
7436                 }
7437
7438                 /* Link. */
7439                 gl.linkProgram(m_po);
7440
7441                 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
7442
7443                 glw::GLint status = GL_FALSE;
7444
7445                 gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
7446
7447                 if (GL_TRUE == status)
7448                 {
7449                         for (glw::GLuint i = 0; i < shader_count; ++i)
7450                         {
7451                                 if (shader[i].id)
7452                                 {
7453                                         gl.detachShader(m_po, shader[i].id);
7454
7455                                         GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
7456                                 }
7457                         }
7458                 }
7459                 else
7460                 {
7461                         glw::GLint log_size = 0;
7462
7463                         gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
7464
7465                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
7466
7467                         glw::GLchar* log_text = new glw::GLchar[log_size];
7468
7469                         gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
7470
7471                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
7472                                                                                                 << log_text << "\n"
7473                                                                                                 << tcu::TestLog::EndMessage;
7474
7475                         delete[] log_text;
7476
7477                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
7478
7479                         throw 0;
7480                 }
7481         }
7482         catch (...)
7483         {
7484                 if (m_po)
7485                 {
7486                         gl.deleteProgram(m_po);
7487
7488                         m_po = 0;
7489                 }
7490         }
7491
7492         for (glw::GLuint i = 0; i < shader_count; ++i)
7493         {
7494                 if (0 != shader[i].id)
7495                 {
7496                         gl.deleteShader(shader[i].id);
7497
7498                         shader[i].id = 0;
7499                 }
7500         }
7501
7502         if (0 == m_po)
7503         {
7504                 throw 0;
7505         }
7506 }
7507
7508 /** Prepare Vertex Array Objects (one for each draw pass).
7509  */
7510 void FunctionalTest::PrepareBuffersAndVertexArrays()
7511 {
7512         /* Shortcut for GL functionality. */
7513         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7514
7515         /* Query program attribute. */
7516         glw::GLuint program_attribute = gl.getAttribLocation(m_po, s_attribute);
7517         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation call failed.");
7518
7519         /* Create stencil pass buffer. */
7520         gl.genVertexArrays(1, &m_vao_stencil_pass_quad);
7521         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
7522
7523         gl.bindVertexArray(m_vao_stencil_pass_quad);
7524         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
7525
7526         gl.genBuffers(1, &m_bo_stencil_pass_quad);
7527         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
7528
7529         gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_stencil_pass_quad);
7530         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers call failed.");
7531
7532         gl.bufferData(GL_ARRAY_BUFFER, s_stencil_pass_quad_size, s_stencil_pass_quad, GL_STATIC_DRAW);
7533         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
7534
7535         gl.vertexAttribPointer(program_attribute, 3, GL_FLOAT, GL_FALSE, 0, NULL);
7536         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
7537
7538         gl.enableVertexAttribArray(program_attribute);
7539         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
7540
7541         /* Create depth pass buffer. */
7542         gl.genVertexArrays(1, &m_vao_depth_pass_quad);
7543         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
7544
7545         gl.bindVertexArray(m_vao_depth_pass_quad);
7546         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
7547
7548         gl.genBuffers(1, &m_bo_depth_pass_quad);
7549         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
7550
7551         gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_depth_pass_quad);
7552         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers call failed.");
7553
7554         gl.bufferData(GL_ARRAY_BUFFER, s_depth_pass_quad_size, s_depth_pass_quad, GL_STATIC_DRAW);
7555         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
7556
7557         gl.vertexAttribPointer(program_attribute, 3, GL_FLOAT, GL_FALSE, 0, NULL);
7558         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
7559
7560         gl.enableVertexAttribArray(program_attribute);
7561         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
7562
7563         /* Create color pass buffer. */
7564         gl.genVertexArrays(1, &m_vao_color_pass_quad);
7565         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
7566
7567         gl.bindVertexArray(m_vao_color_pass_quad);
7568         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
7569
7570         gl.genBuffers(1, &m_bo_color_pass_quad);
7571         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
7572
7573         gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_color_pass_quad);
7574         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers call failed.");
7575
7576         gl.bufferData(GL_ARRAY_BUFFER, s_color_pass_quad_size, s_color_pass_quad, GL_STATIC_DRAW);
7577         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
7578
7579         gl.vertexAttribPointer(program_attribute, 3, GL_FLOAT, GL_FALSE, 0, NULL);
7580         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
7581
7582         gl.enableVertexAttribArray(program_attribute);
7583         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
7584 }
7585
7586 /** Do the test draww/blit calls.
7587  *
7588  *  @return True if there is no error in DSA functionality, false otherwise.
7589  */
7590 bool FunctionalTest::DrawAndBlit()
7591 {
7592         /* Shortcut for GL functionality. */
7593         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7594
7595         gl.useProgram(m_po);
7596         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
7597
7598         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_1st);
7599         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
7600
7601         gl.viewport(0, 0, 8, 8);
7602         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport call failed.");
7603
7604         /* Draw to stencil buffer. */
7605         gl.bindVertexArray(m_vao_stencil_pass_quad);
7606         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
7607
7608         gl.stencilFunc(GL_NEVER, 0, 0xff);
7609         GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc call failed.");
7610
7611         gl.stencilOp(GL_INCR, GL_KEEP, GL_KEEP);
7612         GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp call failed.");
7613
7614         gl.stencilMask(0xff);
7615         GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilMask call failed.");
7616
7617         gl.colorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
7618         GLU_EXPECT_NO_ERROR(gl.getError(), "glColorMask call failed.");
7619
7620         gl.depthMask(GL_FALSE);
7621         GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthMask call failed.");
7622
7623         gl.enable(GL_STENCIL_TEST);
7624         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
7625
7626         gl.disable(GL_DEPTH_TEST);
7627         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
7628
7629         gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
7630         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
7631
7632         /* Draw to depth buffer. */
7633         gl.bindVertexArray(m_vao_depth_pass_quad);
7634         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
7635
7636         gl.stencilFunc(GL_ALWAYS, 0, 0xff);
7637         GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc call failed.");
7638
7639         gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
7640         GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp call failed.");
7641
7642         gl.stencilMask(0xff);
7643         GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilMask call failed.");
7644
7645         gl.depthFunc(GL_ALWAYS);
7646         GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc call failed.");
7647
7648         gl.disable(GL_STENCIL_TEST);
7649         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable call failed.");
7650
7651         gl.enable(GL_DEPTH_TEST);
7652         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
7653
7654         gl.depthMask(GL_TRUE);
7655         GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthMask call failed.");
7656
7657         gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
7658         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
7659
7660         /* Draw to color buffer. */
7661         gl.bindVertexArray(m_vao_color_pass_quad);
7662         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
7663
7664         gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
7665         GLU_EXPECT_NO_ERROR(gl.getError(), "glColorMask call failed.");
7666
7667         gl.stencilFunc(GL_EQUAL, 1, 0xff);
7668         GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc call failed.");
7669
7670         gl.enable(GL_STENCIL_TEST);
7671         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
7672
7673         gl.enable(GL_DEPTH_TEST);
7674         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable call failed.");
7675
7676         gl.depthFunc(GL_GREATER);
7677         GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc call failed.");
7678
7679         gl.depthMask(GL_FALSE);
7680         GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthMask call failed.");
7681
7682         gl.drawArrays(GL_TRIANGLE_STRIP, 0, 4);
7683         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
7684
7685         /* Blit framebuffer content. */
7686         gl.blitNamedFramebuffer(m_fbo_1st, m_fbo_2nd, 0, 0, 8, 8, 0, 0, 4, 3, GL_COLOR_BUFFER_BIT, GL_NEAREST);
7687
7688         if (gl.getError())
7689         {
7690                 return false;
7691         }
7692
7693         return true;
7694 }
7695
7696 /** Check resulting framebuffer content.
7697  *
7698  *  @return True if content matches the reference false otherwise.
7699  */
7700 bool FunctionalTest::CheckSecondFramebufferContent()
7701 {
7702         /* Shortcut for GL functionality. */
7703         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7704
7705         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_2nd);
7706         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
7707
7708         glw::GLubyte framebuffer_values[3][4] = {
7709                 { 0 } /* , ... */
7710         };
7711
7712         static const glw::GLubyte reference_values[3][4] = { { 0, 0, 0, 0 }, { 0, 0, 255, 0 }, { 0, 0, 0, 0 } };
7713
7714         gl.readPixels(0, 0, 4, 3, GL_RED, GL_UNSIGNED_BYTE, framebuffer_values);
7715         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
7716
7717         for (glw::GLuint j = 0; j < 3; ++j)
7718         {
7719                 for (glw::GLuint i = 0; i < 4; ++i)
7720                 {
7721                         if (reference_values[j][i] != framebuffer_values[j][i])
7722                         {
7723                                 return false;
7724                         }
7725                 }
7726         }
7727
7728         return true;
7729 }
7730
7731 /** @brief Clean up GL state.
7732  */
7733 void FunctionalTest::Clean()
7734 {
7735         /* Shortcut for GL functionality. */
7736         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7737
7738         /* Releas GL objects. */
7739         if (m_fbo_1st)
7740         {
7741                 gl.deleteFramebuffers(1, &m_fbo_1st);
7742
7743                 m_fbo_1st = 0;
7744         }
7745
7746         if (m_fbo_2nd)
7747         {
7748                 gl.deleteFramebuffers(1, &m_fbo_2nd);
7749
7750                 m_fbo_2nd = 0;
7751         }
7752
7753         if (m_rbo_color)
7754         {
7755                 gl.deleteRenderbuffers(1, &m_rbo_color);
7756
7757                 m_rbo_color = 0;
7758         }
7759
7760         if (m_rbo_depth_stencil)
7761         {
7762                 gl.deleteRenderbuffers(1, &m_rbo_depth_stencil);
7763
7764                 m_rbo_depth_stencil = 0;
7765         }
7766
7767         if (m_to_color)
7768         {
7769                 gl.deleteTextures(1, &m_to_color);
7770
7771                 m_to_color = 0;
7772         }
7773
7774         if (m_po)
7775         {
7776                 gl.useProgram(0);
7777
7778                 gl.deleteProgram(m_po);
7779
7780                 m_po = 0;
7781         }
7782
7783         if (m_vao_stencil_pass_quad)
7784         {
7785                 gl.deleteBuffers(1, &m_vao_stencil_pass_quad);
7786
7787                 m_vao_stencil_pass_quad = 0;
7788         }
7789
7790         if (m_vao_depth_pass_quad)
7791         {
7792                 gl.deleteBuffers(1, &m_vao_depth_pass_quad);
7793
7794                 m_vao_depth_pass_quad = 0;
7795         }
7796
7797         if (m_vao_color_pass_quad)
7798         {
7799                 gl.deleteBuffers(1, &m_vao_color_pass_quad);
7800
7801                 m_vao_color_pass_quad = 0;
7802         }
7803
7804         if (m_bo_stencil_pass_quad)
7805         {
7806                 gl.deleteBuffers(1, &m_bo_stencil_pass_quad);
7807
7808                 m_bo_stencil_pass_quad = 0;
7809         }
7810
7811         if (m_bo_depth_pass_quad)
7812         {
7813                 gl.deleteBuffers(1, &m_bo_depth_pass_quad);
7814
7815                 m_bo_depth_pass_quad = 0;
7816         }
7817
7818         if (m_bo_color_pass_quad)
7819         {
7820                 gl.deleteBuffers(1, &m_bo_color_pass_quad);
7821
7822                 m_bo_color_pass_quad = 0;
7823         }
7824
7825         /* Reseting state. */
7826         gl.stencilFunc(GL_ALWAYS, 0, 0xff);
7827         gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
7828         gl.stencilMask(0xff);
7829         gl.colorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
7830         gl.depthFunc(GL_LESS);
7831         gl.depthMask(GL_TRUE);
7832         gl.disable(GL_STENCIL_TEST);
7833         gl.disable(GL_DEPTH_TEST);
7834
7835         /* Clean errors. */
7836         while (gl.getError())
7837                 ;
7838 }
7839
7840 /** Vertex shader source code. */
7841 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 330\n"
7842                                                                                                           "\n"
7843                                                                                                           "in vec3 position;\n"
7844                                                                                                           "\n"
7845                                                                                                           "void main()\n"
7846                                                                                                           "{\n"
7847                                                                                                           "    gl_Position = vec4(position, 1.0);\n"
7848                                                                                                           "}\n";
7849
7850 /** Fragment shader source code. */
7851 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 330\n"
7852                                                                                                                 "\n"
7853                                                                                                                 "out vec4 color;\n"
7854                                                                                                                 "\n"
7855                                                                                                                 "void main()\n"
7856                                                                                                                 "{\n"
7857                                                                                                                 "    color = vec4(1.0);\n"
7858                                                                                                                 "}\n";
7859
7860 /** Vertex shader source code attribute name. */
7861 const glw::GLchar FunctionalTest::s_attribute[] = "position";
7862
7863 /** Stencil pass' geometry to be passed to vertex shader attribute. */
7864 const glw::GLfloat FunctionalTest::s_stencil_pass_quad[] = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
7865                                                                                                                          0.5f,  -0.5f, 0.5f, 0.5f,  0.5f, 0.5f };
7866
7867 /** Depth pass' geometry to be passed to vertex shader attribute. */
7868 const glw::GLfloat FunctionalTest::s_depth_pass_quad[] = { -1.0f, -1.0f, 1.0f,  -1.0f, 1.0f, 1.0f,
7869                                                                                                                    1.0f,  -1.0f, -1.0f, 1.0f,  1.0f, -1.0f };
7870
7871 /** Color pass' geometry to be passed to vertex shader attribute. */
7872 const glw::GLfloat FunctionalTest::s_color_pass_quad[] = { -1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f,
7873                                                                                                                    1.0f,  -1.0f, 0.0f, 1.0f,  1.0f, 0.0f };
7874
7875 const glw::GLuint FunctionalTest::s_stencil_pass_quad_size =
7876         sizeof(s_stencil_pass_quad); //!< Size of stencil pass' geometry.
7877 const glw::GLuint FunctionalTest::s_depth_pass_quad_size =
7878         sizeof(s_depth_pass_quad); //!< Size of depth   pass' geometry.
7879 const glw::GLuint FunctionalTest::s_color_pass_quad_size =
7880         sizeof(s_color_pass_quad); //!< Size of color   pass' geometry.
7881
7882 } // namespace Framebuffers
7883
7884 namespace Renderbuffers
7885 {
7886 /******************************** Renderbuffer Creation Test Implementation   ********************************/
7887
7888 /** @brief Creation Test constructor.
7889  *
7890  *  @param [in] context     OpenGL context.
7891  */
7892 CreationTest::CreationTest(deqp::Context& context)
7893         : deqp::TestCase(context, "renderbuffers_creation", "Renderbuffer Objects Creation Test")
7894 {
7895         /* Intentionally left blank. */
7896 }
7897
7898 /** @brief Iterate Creation Test cases.
7899  *
7900  *  @return Iteration result.
7901  */
7902 tcu::TestNode::IterateResult CreationTest::iterate()
7903 {
7904         /* Shortcut for GL functionality. */
7905         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
7906
7907         /* Get context setup. */
7908         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
7909         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
7910
7911         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
7912         {
7913                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
7914
7915                 return STOP;
7916         }
7917
7918         /* Running tests. */
7919         bool is_ok      = true;
7920         bool is_error = false;
7921
7922         /* Renderbuffers' objects */
7923         static const glw::GLuint renderbuffers_count = 2;
7924
7925         glw::GLuint renderbuffers_legacy[renderbuffers_count] = {};
7926         glw::GLuint renderbuffers_dsa[renderbuffers_count]      = {};
7927
7928         try
7929         {
7930                 /* Check legacy state creation. */
7931                 gl.genRenderbuffers(renderbuffers_count, renderbuffers_legacy);
7932                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
7933
7934                 for (glw::GLuint i = 0; i < renderbuffers_count; ++i)
7935                 {
7936                         if (gl.isRenderbuffer(renderbuffers_legacy[i]))
7937                         {
7938                                 is_ok = false;
7939
7940                                 /* Log. */
7941                                 m_context.getTestContext().getLog()
7942                                         << tcu::TestLog::Message
7943                                         << "GenRenderbuffers has created default objects, but it should create only a names."
7944                                         << tcu::TestLog::EndMessage;
7945                         }
7946                 }
7947
7948                 /* Check direct state creation. */
7949                 gl.createRenderbuffers(renderbuffers_count, renderbuffers_dsa);
7950                 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateRenderbuffers has failed");
7951
7952                 for (glw::GLuint i = 0; i < renderbuffers_count; ++i)
7953                 {
7954                         if (!gl.isRenderbuffer(renderbuffers_dsa[i]))
7955                         {
7956                                 is_ok = false;
7957
7958                                 /* Log. */
7959                                 m_context.getTestContext().getLog() << tcu::TestLog::Message
7960                                                                                                         << "CreateRenderbuffers has not created default objects."
7961                                                                                                         << tcu::TestLog::EndMessage;
7962                         }
7963                 }
7964         }
7965         catch (...)
7966         {
7967                 is_ok   = false;
7968                 is_error = true;
7969         }
7970
7971         /* Cleanup. */
7972         for (glw::GLuint i = 0; i < renderbuffers_count; ++i)
7973         {
7974                 if (renderbuffers_legacy[i])
7975                 {
7976                         gl.deleteRenderbuffers(1, &renderbuffers_legacy[i]);
7977
7978                         renderbuffers_legacy[i] = 0;
7979                 }
7980
7981                 if (renderbuffers_dsa[i])
7982                 {
7983                         gl.deleteRenderbuffers(1, &renderbuffers_dsa[i]);
7984
7985                         renderbuffers_dsa[i] = 0;
7986                 }
7987         }
7988
7989         /* Errors clean up. */
7990         while (gl.getError())
7991                 ;
7992
7993         /* Result's setup. */
7994         if (is_ok)
7995         {
7996                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
7997         }
7998         else
7999         {
8000                 if (is_error)
8001                 {
8002                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8003                 }
8004                 else
8005                 {
8006                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8007                 }
8008         }
8009
8010         return STOP;
8011 }
8012
8013 /******************************** Renderbuffer Storage Test Implementation   ********************************/
8014
8015 /** @brief Renderbuffer Storage Test constructor.
8016  *
8017  *  @param [in] context     OpenGL context.
8018  */
8019 StorageTest::StorageTest(deqp::Context& context)
8020         : deqp::TestCase(context, "renderbuffers_storage", "Renderbuffer Objects Storage Test"), m_fbo(0), m_rbo(0)
8021 {
8022         /* Intentionally left blank. */
8023 }
8024
8025 /** @brief Iterate Creation Test cases.
8026  *
8027  *  @return Iteration result.
8028  */
8029 tcu::TestNode::IterateResult StorageTest::iterate()
8030 {
8031         /* Shortcut for GL functionality. */
8032         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8033
8034         /* Get context setup. */
8035         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8036         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8037
8038         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8039         {
8040                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8041
8042                 return STOP;
8043         }
8044
8045         /* Running tests. */
8046         bool is_ok      = true;
8047         bool is_error = false;
8048
8049         try
8050         {
8051                 glw::GLint max_renderbuffer_size = 16384 /* Specification minimum. */;
8052
8053                 gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_renderbuffer_size);
8054                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
8055
8056                 const struct
8057                 {
8058                         glw::GLuint width;
8059                         glw::GLuint height;
8060                 } test_cases[] = { { 1, 1 },
8061                                                    { 256, 512 },
8062                                                    { 1280, 720 },
8063                                                    { (glw::GLuint)max_renderbuffer_size, 1 },
8064                                                    { 1, (glw::GLuint)max_renderbuffer_size } };
8065
8066                 const glw::GLuint test_cases_count = sizeof(test_cases) / sizeof(test_cases[0]);
8067
8068                 for (glw::GLuint i = 0; i < test_cases_count; ++i)
8069                 {
8070                         for (glw::GLuint j = 0; j < s_renderbuffer_internalformat_configuration_count; ++j)
8071                         {
8072                                 if (PrepareRenderbuffer(s_renderbuffer_internalformat_configuration[j], test_cases[i].width,
8073                                                                                 test_cases[i].height))
8074                                 {
8075                                         Clear(s_renderbuffer_internalformat_configuration[j].isColorIntegralFormat);
8076                                         is_ok &= Check(s_renderbuffer_internalformat_configuration[j], test_cases[i].width,
8077                                                                    test_cases[i].height);
8078                                 }
8079                                 else
8080                                 {
8081                                         is_ok = false;
8082                                 }
8083
8084                                 Clean();
8085                         }
8086                 }
8087         }
8088         catch (...)
8089         {
8090                 is_ok   = false;
8091                 is_error = true;
8092
8093                 Clean();
8094         }
8095
8096         /* Result's setup. */
8097         if (is_ok)
8098         {
8099                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8100         }
8101         else
8102         {
8103                 if (is_error)
8104                 {
8105                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8106                 }
8107                 else
8108                 {
8109                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8110                 }
8111         }
8112
8113         return STOP;
8114 }
8115
8116 /** Prepare renderbuffer.
8117  *
8118  *  @param [in] format              Internal format to be prepared.
8119  *  @param [in] width               Width of the framebuffer.
8120  *  @param [in] height              Height of the framebuffer.
8121  *
8122  *  @return True if there is no error, false otherwise.
8123  */
8124 bool StorageTest::PrepareRenderbuffer(StorageTest::RenderbufferInternalFormatConfiguration format, glw::GLuint width,
8125                                                                           glw::GLuint height)
8126 {
8127         /* Shortcut for GL functionality. */
8128         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8129
8130         gl.genFramebuffers(1, &m_fbo);
8131         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
8132
8133         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
8134         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
8135
8136         gl.createRenderbuffers(1, &m_rbo);
8137         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateRenderbuffers call failed.");
8138
8139         gl.namedRenderbufferStorage(m_rbo, format.internalformat, width, height);
8140
8141         if (glw::GLenum error = gl.getError())
8142         {
8143                 m_context.getTestContext().getLog()
8144                         << tcu::TestLog::Message << "Renderbuffer storage test failed because NamedRenderbufferStorage generated "
8145                         << glu::getErrorStr(error) << " error value. Renderbuffers format was "
8146                         << glu::getInternalFormatParameterStr(format.internalformat) << ", width was " << width << ", height was "
8147                         << height << "." << tcu::TestLog::EndMessage;
8148                 return false;
8149         }
8150
8151         if (format.hasRedComponent || format.hasGreenComponent || format.hasBlueComponent || format.hasAlphaComponent)
8152         {
8153                 gl.namedFramebufferRenderbuffer(m_fbo, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo);
8154         }
8155
8156         if (format.hasDepthComponent)
8157         {
8158                 gl.namedFramebufferRenderbuffer(m_fbo, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbo);
8159         }
8160
8161         if (format.hasStencilComponent)
8162         {
8163                 gl.namedFramebufferRenderbuffer(m_fbo, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo);
8164         }
8165
8166         if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
8167         {
8168                 /* Log. */
8169                 m_context.getTestContext().getLog()
8170                         << tcu::TestLog::Message
8171                         << "Renderbuffer storage test failed due to incomplete framebuffer status. Renderbuffers format was "
8172                         << glu::getInternalFormatParameterStr(format.internalformat) << ", width was " << width << ", height was "
8173                         << height << "." << tcu::TestLog::EndMessage;
8174
8175                 return false;
8176         }
8177
8178         return true;
8179 }
8180
8181 /** Clear renderbuffer.
8182  *
8183  *  @param [in] isColorIntegralFormat       Is this color integral format.
8184  */
8185 void StorageTest::Clear(bool isColorIntegralFormat)
8186 {
8187         /* Shortcut for GL functionality. */
8188         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8189         if (isColorIntegralFormat)
8190         {
8191                 gl.clearBufferiv(GL_COLOR, 0, s_reference_color_integer);
8192                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferiv has failed");
8193         }
8194         else
8195         {
8196                 /* Setup clear values. */
8197                 gl.clearColor(s_reference_color[0], s_reference_color[1], s_reference_color[2], s_reference_color[3]);
8198                 gl.clearDepth(s_reference_depth);
8199                 gl.clearStencil(s_reference_stencil);
8200
8201                 /* Clear rbo/fbo. */
8202                 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
8203         }
8204 }
8205
8206 /** Check renderbuffer's content.
8207  *
8208  *  @param [in] format              Internal format to be prepared.
8209  *  @param [in] width               Width of the framebuffer.
8210  *  @param [in] height              Height of the framebuffer.
8211  *
8212  *  @return True if content matches the reference, false otherwise.
8213  */
8214 bool StorageTest::Check(StorageTest::RenderbufferInternalFormatConfiguration format, glw::GLuint width,
8215                                                 glw::GLuint height)
8216 {
8217         /* Shortcut for GL functionality. */
8218         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8219
8220         glw::GLuint size = width * height;
8221
8222         if (format.hasRedComponent || format.hasGreenComponent || format.hasBlueComponent || format.hasAlphaComponent)
8223         {
8224                 if (format.isColorIntegralFormat)
8225                 {
8226                         std::vector<glw::GLint> color(size * 4);
8227
8228                         gl.readPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_INT, &color[0]);
8229                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
8230
8231                         const bool hasComponent[] = { format.hasRedComponent, format.hasGreenComponent, format.hasBlueComponent,
8232                                                                                   format.hasAlphaComponent };
8233
8234                         static const char* componentName[] = { "red", "green", "blue", "alpha" };
8235
8236                         for (glw::GLuint i = 0; i < size; ++i)
8237                         {
8238                                 if (hasComponent[i % 4 /* color components count*/])
8239                                 {
8240                                         if (de::abs(s_reference_color_integer[i % 4 /* color components count*/] - color[i]) >
8241                                                 2 /* Precision */)
8242                                         {
8243                                                 m_context.getTestContext().getLog()
8244                                                         << tcu::TestLog::Message << "Renderbuffer storage was cleared with color "
8245                                                         << componentName[i % 4 /* color components count*/] << " component equal to "
8246                                                         << s_reference_color_integer << ", but fetched value " << color[i]
8247                                                         << " is not the same. Renderbuffers format was " << format.internalformat_name
8248                                                         << ", width was " << width << ", height was " << height << "." << tcu::TestLog::EndMessage;
8249
8250                                                 return false;
8251                                         }
8252                                 }
8253                         }
8254                 }
8255                 else
8256                 {
8257                         std::vector<glw::GLfloat> color(size * 4);
8258
8259                         gl.readPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, &color[0]);
8260                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
8261
8262                         const bool hasComponent[] = { format.hasRedComponent, format.hasGreenComponent, format.hasBlueComponent,
8263                                                                                   format.hasAlphaComponent };
8264
8265                         static const char* componentName[] = { "red", "green", "blue", "alpha" };
8266
8267                         for (glw::GLuint i = 0; i < size; ++i)
8268                         {
8269                                 if (hasComponent[i % 4 /* color components count*/])
8270                                 {
8271                                         if (de::abs(s_reference_color[i % 4 /* color components count*/] - color[i]) >
8272                                                 0.0625 /* precision */)
8273                                         {
8274                                                 m_context.getTestContext().getLog()
8275                                                         << tcu::TestLog::Message << "Renderbuffer storage was cleared with color "
8276                                                         << componentName[i % 4 /* color components count*/] << " component equal to "
8277                                                         << s_reference_color[i % 4 /* color components count*/] << ", but fetched value "
8278                                                         << color[i] << " is not the same. Renderbuffers format was " << format.internalformat_name
8279                                                         << ", width was " << width << ", height was " << height << "." << tcu::TestLog::EndMessage;
8280
8281                                                 return false;
8282                                         }
8283                                 }
8284                         }
8285                 }
8286         }
8287
8288         if (format.hasDepthComponent)
8289         {
8290                 std::vector<glw::GLfloat> depth(size);
8291
8292                 gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, &depth[0]);
8293                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
8294
8295                 for (glw::GLuint i = 0; i < size; ++i)
8296                 {
8297                         if (de::abs(s_reference_depth - depth[i]) > 0.0625 /* 1/16 precision */)
8298                         {
8299                                 m_context.getTestContext().getLog()
8300                                         << tcu::TestLog::Message << "Renderbuffer storage was cleared with depth component equal to "
8301                                         << s_reference_depth << ", but fetched value " << depth[i]
8302                                         << " is not the same. Renderbuffers format was " << format.internalformat_name << ", width was "
8303                                         << width << ", height was " << height << "." << tcu::TestLog::EndMessage;
8304
8305                                 return false;
8306                         }
8307                 }
8308         }
8309
8310         if (format.hasStencilComponent)
8311         {
8312                 std::vector<glw::GLint> stencil(size);
8313
8314                 gl.readPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_INT, &stencil[0]);
8315                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
8316
8317                 for (glw::GLuint i = 0; i < size; ++i)
8318                 {
8319                         if (s_reference_stencil != stencil[i])
8320                         {
8321                                 m_context.getTestContext().getLog()
8322                                         << tcu::TestLog::Message << "Renderbuffer storage was cleared with alpha component equal to "
8323                                         << s_reference_stencil << ", but fetched value " << stencil[i]
8324                                         << " is not the same. Renderbuffers format was " << format.internalformat_name << ", width was "
8325                                         << width << ", height was " << height << "." << tcu::TestLog::EndMessage;
8326
8327                                 return false;
8328                         }
8329                 }
8330         }
8331
8332         return true;
8333 }
8334
8335 /** @brief Clean up GL state.
8336  */
8337 void StorageTest::Clean()
8338 {
8339         /* Shortcut for GL functionality. */
8340         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8341
8342         /* Release objects. */
8343         if (m_rbo)
8344         {
8345                 gl.deleteRenderbuffers(1, &m_rbo);
8346
8347                 m_rbo = 0;
8348         }
8349
8350         if (m_fbo)
8351         {
8352                 gl.deleteFramebuffers(1, &m_fbo);
8353
8354                 m_fbo = 0;
8355         }
8356
8357         /* Returning to default clear values. */
8358         gl.clearColor(0.f, 0.f, 0.f, 0.f);
8359         gl.clearDepth(1.f);
8360         gl.clearStencil(0);
8361
8362         /* Errors clean up. */
8363         while (gl.getError())
8364                 ;
8365 }
8366
8367 /** Internal formats to be tested*/
8368 const struct StorageTest::RenderbufferInternalFormatConfiguration
8369         StorageTest::s_renderbuffer_internalformat_configuration[] = {
8370                 { GL_R8, "GL_R8", true, false, false, false, false, false, false },
8371                 { GL_R16, "GL_R16", true, false, false, false, false, false, false },
8372                 { GL_RG8, "GL_RG8", true, true, false, false, false, false, false },
8373                 { GL_RG16, "GL_RG16", true, true, false, false, false, false, false },
8374                 { GL_RGB565, "GL_RGB56", true, true, true, false, false, false, false },
8375                 { GL_RGBA4, "GL_RGBA4", true, true, true, true, false, false, false },
8376                 { GL_RGB5_A1, "GL_RGB5_A1", true, true, true, true, false, false, false },
8377                 { GL_RGBA8, "GL_RGBA8", true, true, true, true, false, false, false },
8378                 { GL_RGB10_A2, "GL_RGB10_A2", true, true, true, true, false, false, false },
8379                 { GL_RGB10_A2UI, "GL_RGB10_A2UI", true, true, true, true, false, false, true },
8380                 { GL_RGBA16, "GL_RGBA16", true, true, true, true, false, false, false },
8381                 { GL_SRGB8_ALPHA8, "GL_SRGB8_ALPHA8", true, true, true, true, false, false, false },
8382                 { GL_R16F, "GL_R16F", true, false, false, false, false, false, false },
8383                 { GL_RG16F, "GL_RG16F", true, true, false, false, false, false, false },
8384                 { GL_RGBA16F, "GL_RGBA16F", true, true, true, true, false, false, false },
8385                 { GL_R32F, "GL_R32F", true, false, false, false, false, false, false },
8386                 { GL_RG32F, "GL_RG32F", true, true, false, false, false, false, false },
8387                 { GL_RGBA32F, "GL_RGBA32F", true, true, true, true, false, false, false },
8388                 { GL_R11F_G11F_B10F, "GL_R11F_G11F_B10F", true, true, true, false, false, false, false },
8389                 { GL_R8I, "GL_R8I", true, false, false, false, false, false, true },
8390                 { GL_R8UI, "GL_R8UI", true, false, false, false, false, false, true },
8391                 { GL_R16I, "GL_R16I", true, false, false, false, false, false, true },
8392                 { GL_R16UI, "GL_R16UI", true, false, false, false, false, false, true },
8393                 { GL_R32I, "GL_R32I", true, false, false, false, false, false, true },
8394                 { GL_R32UI, "GL_R32UI", true, false, false, false, false, false, true },
8395                 { GL_RG8I, "GL_RG8I", true, true, false, false, false, false, true },
8396                 { GL_RG8UI, "GL_RG8UI", true, true, false, false, false, false, true },
8397                 { GL_RG16I, "GL_RG16I", true, true, false, false, false, false, true },
8398                 { GL_RG16UI, "GL_RG16UI", true, true, false, false, false, false, true },
8399                 { GL_RG32I, "GL_RG32I", true, true, false, false, false, false, true },
8400                 { GL_RG32UI, "GL_RG32UI", true, true, false, false, false, false, true },
8401                 { GL_RGBA8I, "GL_RGBA8I", true, true, true, true, false, false, true },
8402                 { GL_RGBA8UI, "GL_RGBA8UI", true, true, true, true, false, false, true },
8403                 { GL_RGBA16I, "GL_RGBA16I", true, true, true, true, false, false, true },
8404                 { GL_RGBA16UI, "GL_RGBA16UI", true, true, true, true, false, false, true },
8405                 { GL_RGBA32I, "GL_RGBA32I", true, true, true, true, false, false, true },
8406                 { GL_RGBA32UI, "GL_RGBA32UI", true, true, true, true, false, false, true },
8407                 { GL_DEPTH_COMPONENT16, "GL_DEPTH_COMPONENT16", false, false, false, false, true, false, false },
8408                 { GL_DEPTH_COMPONENT24, "GL_DEPTH_COMPONENT24", false, false, false, false, true, false, false },
8409                 { GL_DEPTH_COMPONENT32F, "GL_DEPTH_COMPONENT32F", false, false, false, false, true, false, false },
8410                 { GL_DEPTH24_STENCIL8, "GL_DEPTH24_STENCIL8", false, false, false, false, true, true, false },
8411                 { GL_DEPTH32F_STENCIL8, "GL_DEPTH32F_STENCIL8", false, false, false, false, true, true, false },
8412                 { GL_STENCIL_INDEX8, "GL_STENCIL_INDEX8", false, false, false, false, false, true, false }
8413         };
8414
8415 /** Internal formats count */
8416 const glw::GLuint StorageTest::s_renderbuffer_internalformat_configuration_count =
8417         sizeof(s_renderbuffer_internalformat_configuration) / sizeof(s_renderbuffer_internalformat_configuration[0]);
8418
8419 const glw::GLfloat StorageTest::s_reference_color[4]             = { 0.25, 0.5, 0.75, 1.0 }; //!< Reference color.
8420 const glw::GLint   StorageTest::s_reference_color_integer[4] = { 1, 2, 3, 4 };                   //!< Reference integral color.
8421 const glw::GLfloat StorageTest::s_reference_depth                        = 0.5;                                          //!< Reference depth.
8422 const glw::GLint   StorageTest::s_reference_stencil                      = 7;                                            //!< Reference stencil.
8423
8424 /***************************** Renderbuffer Storage Multisample Test Implementation   ***************************/
8425
8426 /** @brief Renderbuffer Storage Multisample Test constructor.
8427  *
8428  *  @param [in] context     OpenGL context.
8429  */
8430 StorageMultisampleTest::StorageMultisampleTest(deqp::Context& context)
8431         : deqp::TestCase(context, "renderbuffers_storage_multisample", "Renderbuffer Objects Storage Multisample Test")
8432 {
8433         for (glw::GLuint i = 0; i < 2; ++i)
8434         {
8435                 m_fbo[i] = 0;
8436                 m_rbo[i] = 0;
8437         }
8438 }
8439
8440 /** @brief Iterate Creation Test cases.
8441  *
8442  *  @return Iteration result.
8443  */
8444 tcu::TestNode::IterateResult StorageMultisampleTest::iterate()
8445 {
8446         /* Shortcut for GL functionality. */
8447         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8448
8449         /* Get context setup. */
8450         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8451         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8452
8453         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8454         {
8455                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8456
8457                 return STOP;
8458         }
8459
8460         /* Running tests. */
8461         bool is_ok      = true;
8462         bool is_error = false;
8463
8464         try
8465         {
8466                 glw::GLint max_renderbuffer_size = 16384 /* Specification minimum. */;
8467
8468                 gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &max_renderbuffer_size);
8469                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
8470
8471                 const struct
8472                 {
8473                         glw::GLuint width;
8474                         glw::GLuint height;
8475                 } test_cases[] = { { 1, 1 },
8476                                                    { (glw::GLuint)max_renderbuffer_size / 2, 1 },
8477                                                    { 1, (glw::GLuint)max_renderbuffer_size / 2 } };
8478
8479                 const glw::GLuint test_cases_count = sizeof(test_cases) / sizeof(test_cases[0]);
8480
8481                 for (glw::GLuint i = 0; i < test_cases_count; ++i)
8482                 {
8483                         for (glw::GLuint j = 0; j < s_renderbuffer_internalformat_configuration_count; ++j)
8484                         {
8485                                 glw::GLint max_integer_samples = GetMaxConformantSampleCount(
8486                                         GL_RENDERBUFFER, s_renderbuffer_internalformat_configuration[j].internalformat);
8487                                 for (glw::GLint k = 0; k <= max_integer_samples; ++k)
8488                                 {
8489                                         if (PrepareRenderbuffer(s_renderbuffer_internalformat_configuration[j], test_cases[i].width,
8490                                                                                         test_cases[i].height, k))
8491                                         {
8492                                                 Bind(GL_DRAW_FRAMEBUFFER, 0);
8493                                                 Clear(s_renderbuffer_internalformat_configuration[j].isColorIntegralFormat);
8494                                                 Bind(GL_READ_FRAMEBUFFER, 0);
8495                                                 Bind(GL_DRAW_FRAMEBUFFER, 1);
8496                                                 Blit(test_cases[i].width, test_cases[i].height);
8497                                                 Bind(GL_READ_FRAMEBUFFER, 1);
8498                                                 is_ok &= Check(s_renderbuffer_internalformat_configuration[j], test_cases[i].width,
8499                                                                            test_cases[i].height);
8500                                         }
8501                                         else
8502                                         {
8503                                                 is_ok = false;
8504                                         }
8505
8506                                         Clean();
8507                                 }
8508                         }
8509                 }
8510         }
8511         catch (...)
8512         {
8513                 is_ok   = false;
8514                 is_error = true;
8515
8516                 Clean();
8517         }
8518
8519         /* Result's setup. */
8520         if (is_ok)
8521         {
8522                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
8523         }
8524         else
8525         {
8526                 if (is_error)
8527                 {
8528                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
8529                 }
8530                 else
8531                 {
8532                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
8533                 }
8534         }
8535
8536         return STOP;
8537 }
8538
8539 /** Prepare renderbuffer.
8540  *
8541  *  @param [in] format              Internal format to be prepared.
8542  *  @param [in] width               Width of the framebuffer.
8543  *  @param [in] height              Height of the framebuffer.
8544  *
8545  *  @return True if there is no error, false otherwise.
8546  */
8547 bool StorageMultisampleTest::PrepareRenderbuffer(StorageMultisampleTest::RenderbufferInternalFormatConfiguration format,
8548                                                                                                  glw::GLuint width, glw::GLuint height, glw::GLsizei samples)
8549 {
8550         /* Shortcut for GL functionality. */
8551         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8552
8553         gl.genFramebuffers(2, m_fbo);
8554         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
8555
8556         gl.createRenderbuffers(2, m_rbo);
8557         GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateRenderbuffers call failed.");
8558
8559         for (glw::GLuint i = 0; i < 2; ++i)
8560         {
8561                 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo[i]);
8562                 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
8563
8564                 if (i)
8565                 {
8566                         /* 2nd is not multisampled. */
8567                         gl.namedRenderbufferStorageMultisample(m_rbo[i], 0, format.internalformat, width, height);
8568
8569                         if (glw::GLenum error = gl.getError())
8570                         {
8571                                 m_context.getTestContext().getLog()
8572                                         << tcu::TestLog::Message << "Renderbuffer storage multisample test failed because "
8573                                                                                                 "NamedRenderbufferStorageMultisample generated "
8574                                         << glu::getErrorStr(error) << " error value. Renderbuffers format was "
8575                                         << format.internalformat_name << ", samples was " << 0 << ", width was " << width << ", height was "
8576                                         << height << "." << tcu::TestLog::EndMessage;
8577                                 return false;
8578                         }
8579                 }
8580                 else
8581                 {
8582                         /* 1st is multisampled. */
8583                         gl.namedRenderbufferStorageMultisample(m_rbo[i], samples, format.internalformat, width, height);
8584
8585                         if (glw::GLenum error = gl.getError())
8586                         {
8587                                 m_context.getTestContext().getLog()
8588                                         << tcu::TestLog::Message << "Renderbuffer storage multisample test failed because "
8589                                                                                                 "NamedRenderbufferStorageMultisample generated "
8590                                         << glu::getErrorStr(error) << " error value. Renderbuffers format was "
8591                                         << format.internalformat_name << ", samples was " << samples << ", width was " << width
8592                                         << ", height was " << height << "." << tcu::TestLog::EndMessage;
8593                                 return false;
8594                         }
8595                 }
8596
8597                 if (format.hasRedComponent || format.hasGreenComponent || format.hasBlueComponent || format.hasAlphaComponent)
8598                 {
8599                         gl.namedFramebufferRenderbuffer(m_fbo[i], GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rbo[i]);
8600                 }
8601
8602                 if (format.hasDepthComponent)
8603                 {
8604                         gl.namedFramebufferRenderbuffer(m_fbo[i], GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_rbo[i]);
8605                 }
8606
8607                 if (format.hasStencilComponent)
8608                 {
8609                         gl.namedFramebufferRenderbuffer(m_fbo[i], GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_rbo[i]);
8610                 }
8611
8612                 glw::GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
8613                 if (status != GL_FRAMEBUFFER_COMPLETE)
8614                 {
8615                         /* Log. */
8616                         m_context.getTestContext().getLog()
8617                                 << tcu::TestLog::Message << "Renderbuffer storage multisample test failed due to "
8618                                 << glu::getFramebufferStatusStr(status) << " framebuffer status. Renderbuffers format was "
8619                                 << format.internalformat_name << ", samples was " << (i ? 0 : samples) << ", width was " << width
8620                                 << ", height was " << height << "." << tcu::TestLog::EndMessage;
8621
8622                         return false;
8623                 }
8624         }
8625
8626         return true;
8627 }
8628
8629 /** Bind framebuffer to the target.
8630  *
8631  *  @param [in] target              Bind to target.
8632  *  @param [in] selector            Index of the framebuffer in framebuffers' arrays.
8633  */
8634 void StorageMultisampleTest::Bind(glw::GLenum target, glw::GLuint selector)
8635 {
8636         /* Shortcut for GL functionality. */
8637         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8638
8639         /* Binding framebuffer. */
8640         gl.bindFramebuffer(target, m_fbo[selector]);
8641         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
8642 }
8643
8644 /** Blit one framebuffer to the second.
8645  *
8646  *  @param [in] width               Width of the framebuffer.
8647  *  @param [in] height              Height of the framebuffer.
8648  *
8649  *  @return True if there is no error, false otherwise.
8650  */
8651 void StorageMultisampleTest::Blit(glw::GLuint width, glw::GLuint height)
8652 {
8653         /* Shortcut for GL functionality. */
8654         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8655
8656         /* Binding framebuffer. */
8657         gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height,
8658                                            GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
8659         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer call failed.");
8660 }
8661
8662 /** Clear framebuffer.
8663  *
8664  *  @param [in] isColorIntegralFormat       Is framebuffer a color integral type.
8665  */
8666 void StorageMultisampleTest::Clear(bool isColorIntegralFormat)
8667 {
8668         /* Shortcut for GL functionality. */
8669         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8670
8671         if (isColorIntegralFormat)
8672         {
8673                 gl.clearBufferiv(GL_COLOR, 0, s_reference_color_integer);
8674                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearBufferiv has failed");
8675         }
8676         else
8677         {
8678                 /* Setup clear values. */
8679                 gl.clearColor(s_reference_color[0], s_reference_color[1], s_reference_color[2], s_reference_color[3]);
8680                 gl.clearDepth(s_reference_depth);
8681                 gl.clearStencil(s_reference_stencil);
8682
8683                 /* Clear rbo/fbo. */
8684                 gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
8685         }
8686 }
8687
8688 /** Check renderbuffer's content.
8689  *
8690  *  @param [in] format              Internal format to be prepared.
8691  *  @param [in] width               Width of the framebuffer.
8692  *  @param [in] height              Height of the framebuffer.
8693  *
8694  *  @return True if content matches the reference, false otherwise.
8695  */
8696 bool StorageMultisampleTest::Check(StorageMultisampleTest::RenderbufferInternalFormatConfiguration format,
8697                                                                    glw::GLuint width, glw::GLuint height)
8698 {
8699         /* Shortcut for GL functionality. */
8700         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8701
8702         glw::GLuint size = width * height;
8703
8704         if (format.hasRedComponent || format.hasGreenComponent || format.hasBlueComponent || format.hasAlphaComponent)
8705         {
8706                 if (format.isColorIntegralFormat)
8707                 {
8708                         std::vector<glw::GLint> color(size * 4);
8709
8710                         gl.readPixels(0, 0, width, height, GL_RGBA_INTEGER, GL_INT, &color[0]);
8711                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
8712
8713                         const bool hasComponent[] = { format.hasRedComponent, format.hasGreenComponent, format.hasBlueComponent,
8714                                                                                   format.hasAlphaComponent };
8715
8716                         static const char* componentName[] = { "red", "green", "blue", "alpha" };
8717
8718                         for (glw::GLuint i = 0; i < size; ++i)
8719                         {
8720                                 if (hasComponent[i % 4 /* color components count*/])
8721                                 {
8722                                         if (de::abs(s_reference_color_integer[i % 4 /* color components count*/] - color[i]) >
8723                                                 2 /* Precision */)
8724                                         {
8725                                                 m_context.getTestContext().getLog()
8726                                                         << tcu::TestLog::Message << "Renderbuffer storage multisample was cleared with color "
8727                                                         << componentName[i % 4 /* color components count*/] << " component equal to "
8728                                                         << s_reference_color_integer << ", but fetched value " << color[i]
8729                                                         << " is not the same. Renderbuffers format was " << format.internalformat_name
8730                                                         << ", width was " << width << ", height was " << height << "." << tcu::TestLog::EndMessage;
8731
8732                                                 return false;
8733                                         }
8734                                 }
8735                         }
8736                 }
8737                 else
8738                 {
8739                         std::vector<glw::GLfloat> color(size * 4);
8740
8741                         gl.readPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, &color[0]);
8742                         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
8743
8744                         const bool hasComponent[] = { format.hasRedComponent, format.hasGreenComponent, format.hasBlueComponent,
8745                                                                                   format.hasAlphaComponent };
8746
8747                         static const char* componentName[] = { "red", "green", "blue", "alpha" };
8748
8749                         for (glw::GLuint i = 0; i < size; ++i)
8750                         {
8751                                 if (hasComponent[i % 4 /* color components count*/])
8752                                 {
8753                                         if (de::abs(s_reference_color[i % 4 /* color components count*/] - color[i]) >
8754                                                 0.0625 /* precision */)
8755                                         {
8756                                                 m_context.getTestContext().getLog()
8757                                                         << tcu::TestLog::Message << "Renderbuffer storage multisample was cleared with color "
8758                                                         << componentName[i % 4 /* color components count*/] << " component equal to "
8759                                                         << s_reference_color[i % 4 /* color components count*/] << ", but fetched value "
8760                                                         << color[i] << " is not the same. Renderbuffers format was " << format.internalformat_name
8761                                                         << ", width was " << width << ", height was " << height << "." << tcu::TestLog::EndMessage;
8762
8763                                                 return false;
8764                                         }
8765                                 }
8766                         }
8767                 }
8768         }
8769
8770         if (format.hasDepthComponent)
8771         {
8772                 std::vector<glw::GLfloat> depth(size);
8773
8774                 gl.readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, &depth[0]);
8775                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
8776
8777                 for (glw::GLuint i = 0; i < size; ++i)
8778                 {
8779                         if (de::abs(s_reference_depth - depth[i]) > 0.0625 /* 1/16 precision */)
8780                         {
8781                                 m_context.getTestContext().getLog()
8782                                         << tcu::TestLog::Message
8783                                         << "Renderbuffer storage multisample was cleared with depth component equal to "
8784                                         << s_reference_depth << ", but fetched value " << depth[i]
8785                                         << " is not the same. Renderbuffers format was " << format.internalformat_name << ", width was "
8786                                         << width << ", height was " << height << "." << tcu::TestLog::EndMessage;
8787
8788                                 return false;
8789                         }
8790                 }
8791         }
8792
8793         if (format.hasStencilComponent)
8794         {
8795                 std::vector<glw::GLint> stencil(size);
8796
8797                 gl.readPixels(0, 0, width, height, GL_STENCIL_INDEX, GL_INT, &stencil[0]);
8798                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels call failed.");
8799
8800                 for (glw::GLuint i = 0; i < size; ++i)
8801                 {
8802                         if (s_reference_stencil != stencil[i])
8803                         {
8804                                 m_context.getTestContext().getLog()
8805                                         << tcu::TestLog::Message
8806                                         << "Renderbuffer storage multisample was cleared with alpha component equal to "
8807                                         << s_reference_stencil << ", but fetched value " << stencil[i]
8808                                         << " is not the same. Renderbuffers format was " << format.internalformat_name << ", width was "
8809                                         << width << ", height was " << height << "." << tcu::TestLog::EndMessage;
8810
8811                                 return false;
8812                         }
8813                 }
8814         }
8815
8816         return true;
8817 }
8818
8819 /** @brief Clean up GL state.
8820  */
8821 void StorageMultisampleTest::Clean()
8822 {
8823         /* Shortcut for GL functionality. */
8824         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8825
8826         /* Release objects. */
8827         for (glw::GLuint i = 0; i < 2; ++i)
8828         {
8829                 if (m_rbo[i])
8830                 {
8831                         gl.deleteRenderbuffers(1, &m_rbo[i]);
8832
8833                         m_rbo[i] = 0;
8834                 }
8835
8836                 if (m_fbo[i])
8837                 {
8838                         gl.deleteFramebuffers(1, &m_fbo[i]);
8839
8840                         m_fbo[i] = 0;
8841                 }
8842         }
8843
8844         /* Returning to default clear values. */
8845         gl.clearColor(0.f, 0.f, 0.f, 0.f);
8846         gl.clearDepth(1.f);
8847         gl.clearStencil(0);
8848
8849         /* Errors clean up. */
8850         while (gl.getError())
8851                 ;
8852 }
8853
8854 /** @brief Retrieve max conformant sample count when GL_NV_internalformat_sample_query is supported
8855  *
8856  *  @param [in] target                  Target indicating usage of internal format
8857  *  @param [in] internalFormat          Internal format about which to retrieve information
8858  *
8859  *  @return Max conformant sample count
8860  */
8861 glw::GLint StorageMultisampleTest::GetMaxConformantSampleCount(glw::GLenum target, glw::GLenum internalFormat)
8862 {
8863         glw::GLint max_conformant_samples = 0;
8864
8865         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8866
8867         /* Return the max conformant sample count if extension is supported */
8868         if (m_context.getContextInfo().isExtensionSupported("GL_NV_internalformat_sample_query"))
8869         {
8870                 glw::GLint gl_sample_counts = 0;
8871                 gl.getInternalformativ(target, internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &gl_sample_counts);
8872                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for GL_NUM_SAMPLE_COUNTS pname");
8873
8874                 /* Check and return the max conformant sample count */
8875                 glw::GLint* gl_supported_samples = new glw::GLint[gl_sample_counts];
8876                 if (gl_supported_samples)
8877                 {
8878                         gl.getInternalformativ(target, internalFormat, GL_SAMPLES, gl_sample_counts, gl_supported_samples);
8879
8880                         for (glw::GLint i = 0; i < gl_sample_counts; i++)
8881                         {
8882                                 glw::GLint isConformant = 0;
8883                                 gl.getInternalformatSampleivNV(target, internalFormat, gl_supported_samples[i], GL_CONFORMANT_NV, 1,
8884                                                                                            &isConformant);
8885                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformatSampleivNV() call(s) failed");
8886
8887                                 if (isConformant && gl_supported_samples[i] > max_conformant_samples)
8888                                 {
8889                                         max_conformant_samples = gl_supported_samples[i];
8890                                 }
8891                         }
8892                         delete[] gl_supported_samples;
8893                 }
8894         }
8895         else
8896         {
8897                 /* Otherwise return GL_MAX_INTEGER_SAMPLES */
8898                 gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &max_conformant_samples);
8899                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed for GL_MAX_INTEGER_SAMPLES pname.");
8900         }
8901
8902         return max_conformant_samples;
8903 }
8904
8905 /** Tested internal format */
8906 const struct StorageMultisampleTest::RenderbufferInternalFormatConfiguration
8907         StorageMultisampleTest::s_renderbuffer_internalformat_configuration[] = {
8908                 { GL_R8, "GL_R8", true, false, false, false, false, false, false },
8909                 { GL_R16, "GL_R16", true, false, false, false, false, false, false },
8910                 { GL_RG8, "GL_RG8", true, true, false, false, false, false, false },
8911                 { GL_RG16, "GL_RG16", true, true, false, false, false, false, false },
8912                 { GL_RGB565, "GL_RGB56", true, true, true, false, false, false, false },
8913                 { GL_RGBA4, "GL_RGBA4", true, true, true, true, false, false, false },
8914                 { GL_RGB5_A1, "GL_RGB5_A1", true, true, true, true, false, false, false },
8915                 { GL_RGBA8, "GL_RGBA8", true, true, true, true, false, false, false },
8916                 { GL_RGB10_A2, "GL_RGB10_A2", true, true, true, true, false, false, false },
8917                 { GL_RGB10_A2UI, "GL_RGB10_A2UI", true, true, true, true, false, false, true },
8918                 { GL_RGBA16, "GL_RGBA16", true, true, true, true, false, false, false },
8919                 { GL_SRGB8_ALPHA8, "GL_SRGB8_ALPHA8", true, true, true, true, false, false, false },
8920                 { GL_R16F, "GL_R16F", true, false, false, false, false, false, false },
8921                 { GL_RG16F, "GL_RG16F", true, true, false, false, false, false, false },
8922                 { GL_RGBA16F, "GL_RGBA16F", true, true, true, true, false, false, false },
8923                 { GL_R32F, "GL_R32F", true, false, false, false, false, false, false },
8924                 { GL_RG32F, "GL_RG32F", true, true, false, false, false, false, false },
8925                 { GL_RGBA32F, "GL_RGBA32F", true, true, true, true, false, false, false },
8926                 { GL_R11F_G11F_B10F, "GL_R11F_G11F_B10F", true, true, true, false, false, false, false },
8927                 { GL_R8I, "GL_R8I", true, false, false, false, false, false, true },
8928                 { GL_R8UI, "GL_R8UI", true, false, false, false, false, false, true },
8929                 { GL_R16I, "GL_R16I", true, false, false, false, false, false, true },
8930                 { GL_R16UI, "GL_R16UI", true, false, false, false, false, false, true },
8931                 { GL_R32I, "GL_R32I", true, false, false, false, false, false, true },
8932                 { GL_R32UI, "GL_R32UI", true, false, false, false, false, false, true },
8933                 { GL_RG8I, "GL_RG8I", true, true, false, false, false, false, true },
8934                 { GL_RG8UI, "GL_RG8UI", true, true, false, false, false, false, true },
8935                 { GL_RG16I, "GL_RG16I", true, true, false, false, false, false, true },
8936                 { GL_RG16UI, "GL_RG16UI", true, true, false, false, false, false, true },
8937                 { GL_RG32I, "GL_RG32I", true, true, false, false, false, false, true },
8938                 { GL_RG32UI, "GL_RG32UI", true, true, false, false, false, false, true },
8939                 { GL_RGBA8I, "GL_RGBA8I", true, true, true, true, false, false, true },
8940                 { GL_RGBA8UI, "GL_RGBA8UI", true, true, true, true, false, false, true },
8941                 { GL_RGBA16I, "GL_RGBA16I", true, true, true, true, false, false, true },
8942                 { GL_RGBA16UI, "GL_RGBA16UI", true, true, true, true, false, false, true },
8943                 { GL_RGBA32I, "GL_RGBA32I", true, true, true, true, false, false, true },
8944                 { GL_RGBA32UI, "GL_RGBA32UI", true, true, true, true, false, false, true },
8945                 { GL_DEPTH_COMPONENT16, "GL_DEPTH_COMPONENT16", false, false, false, false, true, false, false },
8946                 { GL_DEPTH_COMPONENT24, "GL_DEPTH_COMPONENT24", false, false, false, false, true, false, false },
8947                 { GL_DEPTH_COMPONENT32F, "GL_DEPTH_COMPONENT32F", false, false, false, false, true, false, false },
8948                 { GL_DEPTH24_STENCIL8, "GL_DEPTH24_STENCIL8", false, false, false, false, true, true, false },
8949                 { GL_DEPTH32F_STENCIL8, "GL_DEPTH32F_STENCIL8", false, false, false, false, true, true, false },
8950                 { GL_STENCIL_INDEX8, "GL_STENCIL_INDEX8", false, false, false, false, false, true, false }
8951         };
8952
8953 /** Tesetd internal format count */
8954 const glw::GLuint StorageMultisampleTest::s_renderbuffer_internalformat_configuration_count =
8955         sizeof(s_renderbuffer_internalformat_configuration) / sizeof(s_renderbuffer_internalformat_configuration[0]);
8956
8957 const glw::GLfloat StorageMultisampleTest::s_reference_color[4] = { 0.25, 0.5, 0.75, 1.0 }; //!< Reference color value.
8958 const glw::GLint   StorageMultisampleTest::s_reference_color_integer[4] = {
8959         1, 2, 3, 4
8960 }; //!< Reference color value for integral color internal formats.
8961 const glw::GLfloat StorageMultisampleTest::s_reference_depth   = 0.5; //!< Reference depth value.
8962 const glw::GLint   StorageMultisampleTest::s_reference_stencil = 7;   //!< Reference stencil value.
8963
8964 /******************************** Get Named Renderbuffer Parameters Test Implementation   ********************************/
8965
8966 /** @brief Get Named Renderbuffer Parameters Test constructor.
8967  *
8968  *  @param [in] context     OpenGL context.
8969  */
8970 GetParametersTest::GetParametersTest(deqp::Context& context)
8971         : deqp::TestCase(context, "renderbuffers_get_parameters", "Get Named Renderbuffer Parameters Test")
8972         , m_fbo(0)
8973         , m_rbo(0)
8974 {
8975         /* Intentionally left blank. */
8976 }
8977
8978 /** @brief Iterate Check Status Test cases.
8979  *
8980  *  @return Iteration result.
8981  */
8982 tcu::TestNode::IterateResult GetParametersTest::iterate()
8983 {
8984         /* Shortcut for GL functionality. */
8985         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
8986
8987         /* Get context setup. */
8988         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
8989         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
8990
8991         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
8992         {
8993                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
8994
8995                 return STOP;
8996         }
8997
8998         /* Running tests. */
8999         bool is_ok      = true;
9000         bool is_error = false;
9001
9002         /* Test renderbuffer. */
9003         glw::GLuint renderbuffer = 0;
9004
9005         /* Test. */
9006         try
9007         {
9008                 static const glw::GLenum internalformats[] = { GL_RGBA8, GL_DEPTH_COMPONENT24, GL_STENCIL_INDEX8,
9009                                                                                                            GL_DEPTH24_STENCIL8 };
9010
9011                 static const glw::GLuint internalformats_count = sizeof(internalformats) / sizeof(internalformats[0]);
9012
9013                 for (glw::GLuint i = 0; i < internalformats_count; ++i)
9014                 {
9015                         gl.genRenderbuffers(1, &renderbuffer);
9016                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenRenderbuffers has failed");
9017
9018                         gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
9019                         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindRenderbuffer has failed");
9020
9021                         gl.renderbufferStorage(GL_RENDERBUFFER, internalformats[i], 1, 2);
9022                         GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorage has failed");
9023
9024                         static const glw::GLenum pnames[] = { GL_RENDERBUFFER_WIDTH,               GL_RENDERBUFFER_HEIGHT,
9025                                                                                                   GL_RENDERBUFFER_INTERNAL_FORMAT, GL_RENDERBUFFER_SAMPLES,
9026                                                                                                   GL_RENDERBUFFER_RED_SIZE,                GL_RENDERBUFFER_GREEN_SIZE,
9027                                                                                                   GL_RENDERBUFFER_BLUE_SIZE,       GL_RENDERBUFFER_ALPHA_SIZE,
9028                                                                                                   GL_RENDERBUFFER_DEPTH_SIZE,     GL_RENDERBUFFER_STENCIL_SIZE };
9029
9030                         static const glw::GLchar* pnames_strings[] = {
9031                                 "GL_RENDERBUFFER_WIDTH",           "GL_RENDERBUFFER_HEIGHT",     "GL_RENDERBUFFER_INTERNAL_FORMAT",
9032                                 "GL_RENDERBUFFER_SAMPLES",       "GL_RENDERBUFFER_RED_SIZE",   "GL_RENDERBUFFER_GREEN_SIZE",
9033                                 "GL_RENDERBUFFER_BLUE_SIZE",   "GL_RENDERBUFFER_ALPHA_SIZE", "GL_RENDERBUFFER_DEPTH_SIZE",
9034                                 "GL_RENDERBUFFER_STENCIL_SIZE"
9035                         };
9036
9037                         for (glw::GLuint j = 0; j < internalformats_count; ++j)
9038                         {
9039                                 glw::GLint parameter_legacy = 0;
9040                                 glw::GLint parameter_dsa        = 0;
9041
9042                                 gl.getRenderbufferParameteriv(GL_RENDERBUFFER, pnames[j], &parameter_legacy);
9043                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetRenderbufferParameteriv has failed");
9044
9045                                 gl.getNamedRenderbufferParameteriv(renderbuffer, pnames[j], &parameter_dsa);
9046
9047                                 if (glw::GLenum error = gl.getError())
9048                                 {
9049                                         m_context.getTestContext().getLog()
9050                                                 << tcu::TestLog::Message << "GetNamedRenderbufferParameteriv unexpectedly generated "
9051                                                 << glu::getErrorStr(error) << " error when called with " << pnames_strings[i]
9052                                                 << " parameter name of renderbuffer with  internalformat = "
9053                                                 << glu::getInternalFormatParameterStr(internalformats[i]) << ", width = 1, height = 2."
9054                                                 << tcu::TestLog::EndMessage;
9055
9056                                         is_ok = false;
9057
9058                                         continue;
9059                                 }
9060
9061                                 if (parameter_legacy != parameter_dsa)
9062                                 {
9063                                         m_context.getTestContext().getLog()
9064                                                 << tcu::TestLog::Message << "GetNamedRenderbufferParameteriv returned " << parameter_dsa
9065                                                 << ", but " << parameter_legacy << " was expected for " << pnames_strings[i]
9066                                                 << " parameter name of renderbuffer with  internalformat = "
9067                                                 << glu::getInternalFormatParameterStr(internalformats[i]) << ", width = 1, height = 2."
9068                                                 << tcu::TestLog::EndMessage;
9069
9070                                         is_ok = false;
9071                                 }
9072                         }
9073
9074                         gl.deleteRenderbuffers(1, &renderbuffer);
9075                         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteRenderbuffers has failed");
9076
9077                         renderbuffer = 0;
9078                 }
9079         }
9080         catch (...)
9081         {
9082                 is_ok   = false;
9083                 is_error = true;
9084         }
9085
9086         /* Clean up. */
9087         if (renderbuffer)
9088         {
9089                 gl.deleteRenderbuffers(1, &renderbuffer);
9090         }
9091
9092         while (gl.getError())
9093                 ;
9094
9095         /* Result's setup. */
9096         if (is_ok)
9097         {
9098                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9099         }
9100         else
9101         {
9102                 if (is_error)
9103                 {
9104                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
9105                 }
9106                 else
9107                 {
9108                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
9109                 }
9110         }
9111
9112         return STOP;
9113 }
9114
9115 /******************************** Renderbuffer Creation Errors Test Implementation   ********************************/
9116
9117 /** @brief Creation Errors Test constructor.
9118  *
9119  *  @param [in] context     OpenGL context.
9120  */
9121 CreationErrorsTest::CreationErrorsTest(deqp::Context& context)
9122         : deqp::TestCase(context, "renderbuffers_creation_errors", "Renderbuffer Objects Creation Errors Test")
9123 {
9124         /* Intentionally left blank. */
9125 }
9126
9127 /** @brief Iterate Creation Test cases.
9128  *
9129  *  @return Iteration result.
9130  */
9131 tcu::TestNode::IterateResult CreationErrorsTest::iterate()
9132 {
9133         /* Shortcut for GL functionality. */
9134         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9135
9136         /* Get context setup. */
9137         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
9138         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
9139
9140         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
9141         {
9142                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
9143
9144                 return STOP;
9145         }
9146
9147         /* Running tests. */
9148         bool is_ok = true;
9149
9150         /* Framebuffer object */
9151         glw::GLuint renderbuffer = 0;
9152
9153         /* Check direct state creation of negative numbers of framebuffers. */
9154         gl.createRenderbuffers(-1, &renderbuffer);
9155
9156         glw::GLenum error = GL_NO_ERROR;
9157
9158         if (GL_INVALID_VALUE != (error = gl.getError()))
9159         {
9160                 m_context.getTestContext().getLog()
9161                         << tcu::TestLog::Message << "CreateRenderbuffers generated " << glu::getErrorStr(error)
9162                         << " error when called with negative number of renderbuffers, but GL_INVALID_VALUE was expected."
9163                         << tcu::TestLog::EndMessage;
9164
9165                 is_ok = false;
9166         }
9167
9168         /* Cleanup (sanity). */
9169         if (renderbuffer)
9170         {
9171                 gl.deleteRenderbuffers(1, &renderbuffer);
9172         }
9173
9174         /* Errors clean up. */
9175         while (gl.getError())
9176                 ;
9177
9178         /* Result's setup. */
9179         if (is_ok)
9180         {
9181                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9182         }
9183         else
9184         {
9185                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
9186         }
9187
9188         return STOP;
9189 }
9190
9191 /******************************** Storage Errors Test Implementation   ********************************/
9192
9193 /** @brief Storage Errors Test constructor.
9194  *
9195  *  @param [in] context     OpenGL context.
9196  */
9197 StorageErrorsTest::StorageErrorsTest(deqp::Context& context)
9198         : deqp::TestCase(context, "renderbuffers_storage_errors", "Storage Errors Test")
9199         , m_rbo_valid(0)
9200         , m_rbo_invalid(0)
9201         , m_internalformat_invalid(0)
9202 {
9203         /* Intentionally left blank. */
9204 }
9205
9206 /** @brief Iterate Creation Test cases.
9207  *
9208  *  @return Iteration result.
9209  */
9210 tcu::TestNode::IterateResult StorageErrorsTest::iterate()
9211 {
9212         /* Shortcut for GL functionality. */
9213         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9214
9215         /* Get context setup. */
9216         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
9217         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
9218
9219         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
9220         {
9221                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
9222
9223                 return STOP;
9224         }
9225
9226         /* Running tests. */
9227         bool is_ok      = true;
9228         bool is_error = false;
9229
9230         try
9231         {
9232                 /* Prepare objects. */
9233                 PrepareObjects();
9234
9235                 /*  Check that INVALID_OPERATION is generated by NamedRenderbufferStorage if
9236                  renderbuffer is not the name of an existing renderbuffer object. */
9237                 gl.namedRenderbufferStorage(m_rbo_invalid, GL_RGBA8, 1, 1);
9238
9239                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedRenderbufferStorage",
9240                                                          "renderbuffer is not the name of an existing renderbuffer object.");
9241
9242                 /*  Check that INVALID_VALUE is generated by NamedRenderbufferStorage if
9243                  either of width or height is negative, or greater than the value of
9244                  MAX_RENDERBUFFER_SIZE. */
9245                 gl.namedRenderbufferStorage(m_rbo_valid, GL_RGBA8, -1, 1);
9246
9247                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedRenderbufferStorage", "either of width is negative.");
9248
9249                 gl.namedRenderbufferStorage(m_rbo_valid, GL_RGBA8, 1, -1);
9250
9251                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedRenderbufferStorage", "either of height is negative.");
9252
9253                 /*  Check that INVALID_ENUM is generated by NamedRenderbufferStorage if
9254                  internalformat is not a color-renderable, depth-renderable, or
9255                  stencil-renderable format. */
9256                 gl.namedRenderbufferStorage(m_rbo_valid, m_internalformat_invalid, 1, 1);
9257
9258                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedRenderbufferStorage", "internalformat is not a color-renderable, "
9259                                                                                                                                                   "depth-renderable, or stencil-renderable "
9260                                                                                                                                                   "format (it is COMPRESSED_RED).");
9261         }
9262         catch (...)
9263         {
9264                 is_ok   = false;
9265                 is_error = true;
9266         }
9267
9268         /* Cleanup. */
9269         Clean();
9270
9271         /* Result's setup. */
9272         if (is_ok)
9273         {
9274                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9275         }
9276         else
9277         {
9278                 if (is_error)
9279                 {
9280                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
9281                 }
9282                 else
9283                 {
9284                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
9285                 }
9286         }
9287
9288         return STOP;
9289 }
9290
9291 /** Check Prepare test's GL objects.
9292  */
9293 void StorageErrorsTest::PrepareObjects()
9294 {
9295         /* Shortcut for GL functionality. */
9296         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9297
9298         /* Valid objects. */
9299         gl.genRenderbuffers(1, &m_rbo_valid);
9300         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
9301
9302         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_valid);
9303         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
9304
9305         /* Invalid objects. */
9306         while (gl.isRenderbuffer(++m_rbo_invalid))
9307                 ;
9308 }
9309
9310 /** Check if error is equal to the expected, log if not.
9311  *
9312  *  @param [in] expected_error      Error to be expected.
9313  *  @param [in] function            Function name which is being tested (to be logged).
9314  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
9315  *
9316  *  @return True if there is no error, false otherwise.
9317  */
9318 bool StorageErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
9319                                                                         const glw::GLchar* conditions)
9320 {
9321         /* Shortcut for GL functionality. */
9322         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9323
9324         bool is_ok = true;
9325
9326         glw::GLenum error = GL_NO_ERROR;
9327
9328         if (expected_error != (error = gl.getError()))
9329         {
9330                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
9331                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
9332                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
9333
9334                 is_ok = false;
9335         }
9336
9337         /* Clean additional possible errors. */
9338         while (gl.getError())
9339                 ;
9340
9341         return is_ok;
9342 }
9343
9344 /** @brief Clean up GL state.
9345  */
9346 void StorageErrorsTest::Clean()
9347 {
9348         /* Shortcut for GL functionality. */
9349         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9350
9351         /* Release GL objects. */
9352         if (m_rbo_valid)
9353         {
9354                 gl.deleteRenderbuffers(1, &m_rbo_valid);
9355                 m_rbo_valid = 0;
9356         }
9357
9358         /*  COmpressed internal formats are not color renderable (OpenGL 4.5 Core PRofile SPecification Chapter 9.4 )*/
9359         m_internalformat_invalid = GL_COMPRESSED_RED;
9360
9361         /* Set initial values - all test shall have the same environment. */
9362         m_rbo_valid   = 0;
9363         m_rbo_invalid = 0;
9364
9365         /* Errors clean up. */
9366         while (gl.getError())
9367                 ;
9368 }
9369
9370 /******************************** Storage Multisample Errors Test Implementation   ********************************/
9371
9372 /** @brief Storage Errors Test constructor.
9373  *
9374  *  @param [in] context     OpenGL context.
9375  */
9376 StorageMultisampleErrorsTest::StorageMultisampleErrorsTest(deqp::Context& context)
9377         : deqp::TestCase(context, "renderbuffers_storage_multisample_errors", "Storage Multisample Errors Test")
9378         , m_rbo_valid(0)
9379         , m_rbo_invalid(0)
9380         , m_internalformat_invalid(0)
9381         , m_max_samples(0)
9382         , m_max_integer_samples(0)
9383 {
9384         /* Intentionally left blank. */
9385 }
9386
9387 /** @brief Iterate Creation Test cases.
9388  *
9389  *  @return Iteration result.
9390  */
9391 tcu::TestNode::IterateResult StorageMultisampleErrorsTest::iterate()
9392 {
9393         /* Shortcut for GL functionality. */
9394         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9395
9396         /* Get context setup. */
9397         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
9398         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
9399
9400         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
9401         {
9402                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
9403
9404                 return STOP;
9405         }
9406
9407         /* Running tests. */
9408         bool is_ok      = true;
9409         bool is_error = false;
9410
9411         try
9412         {
9413                 /* Prepare objects. */
9414                 PrepareObjects();
9415
9416                 /*  Check that INVALID_OPERATION is generated by NamedRenderbufferStorage if
9417                  renderbuffer is not the name of an existing renderbuffer object. */
9418                 gl.namedRenderbufferStorageMultisample(m_rbo_invalid, 1, GL_RGBA8, 1, 1);
9419
9420                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedRenderbufferStorageMultisample",
9421                                                          "renderbuffer is not the name of an existing renderbuffer object.");
9422
9423                 /*  Check that INVALID_VALUE is generated by
9424                  NamedRenderbufferStorageMultisample if samples is greater than
9425                  the maximum number of SAMPLES reported for GL_RGBA8. */
9426                 gl.namedRenderbufferStorageMultisample(m_rbo_valid, m_max_samples + 1, GL_RGBA8, 1, 1);
9427
9428                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedRenderbufferStorageMultisample",
9429                                                          "samples is greater than MAX_SAMPLES.");
9430
9431                 /*  Check that INVALID_VALUE is generated by NamedRenderbufferStorage if
9432                  either of width or height is negative, or greater than the value of
9433                  MAX_RENDERBUFFER_SIZE. */
9434                 gl.namedRenderbufferStorageMultisample(m_rbo_valid, 1, GL_RGBA8, -1, 1);
9435
9436                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedRenderbufferStorageMultisample", "either of width is negative.");
9437
9438                 gl.namedRenderbufferStorageMultisample(m_rbo_valid, 1, GL_RGBA8, 1, -1);
9439
9440                 is_ok &= ExpectError(GL_INVALID_VALUE, "NamedRenderbufferStorageMultisample", "either of height is negative.");
9441
9442                 /*  Check that INVALID_OPERATION is generated by
9443                  NamedRenderbufferStorageMultisample if internalformat is a signed or
9444                  unsigned integer format and samples is greater than the maximum number
9445                  of samples reported for GL_RGB10_A2UI */
9446                 gl.namedRenderbufferStorageMultisample(m_rbo_valid, m_max_integer_samples + 1, GL_RGB10_A2UI, 1, 1);
9447
9448                 is_ok &= ExpectError(GL_INVALID_OPERATION, "NamedRenderbufferStorageMultisample",
9449                                                          "internalformat is a signed or unsigned integer format and samples is greater than the "
9450                                                          "value of MAX_INTEGER_SAMPLES.");
9451
9452                 /*  Check that INVALID_ENUM is generated by NamedRenderbufferStorage if
9453                  internalformat is not a color-renderable, depth-renderable, or
9454                  stencil-renderable format. */
9455                 gl.namedRenderbufferStorageMultisample(m_rbo_valid, 1, m_internalformat_invalid, 1, 1);
9456
9457                 is_ok &= ExpectError(GL_INVALID_ENUM, "NamedRenderbufferStorageMultisample",
9458                                                          "internalformat is not a color-renderable, depth-renderable, or stencil-renderable format "
9459                                                          "(it is COMPRESSED_RED).");
9460         }
9461         catch (...)
9462         {
9463                 is_ok   = false;
9464                 is_error = true;
9465         }
9466
9467         /* Cleanup. */
9468         Clean();
9469
9470         /* Result's setup. */
9471         if (is_ok)
9472         {
9473                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9474         }
9475         else
9476         {
9477                 if (is_error)
9478                 {
9479                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
9480                 }
9481                 else
9482                 {
9483                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
9484                 }
9485         }
9486
9487         return STOP;
9488 }
9489
9490 /** Check Prepare test's GL objects.
9491  */
9492 void StorageMultisampleErrorsTest::PrepareObjects()
9493 {
9494         /* Shortcut for GL functionality. */
9495         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9496
9497         /* Valid objects. */
9498         gl.genRenderbuffers(1, &m_rbo_valid);
9499         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
9500
9501         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_valid);
9502         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
9503
9504         /* Limits. */
9505         gl.getInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &m_max_samples);
9506         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ has failed");
9507
9508         gl.getInternalformativ(GL_RENDERBUFFER, GL_RGB10_A2UI, GL_SAMPLES, 1, &m_max_integer_samples);
9509         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ has failed");
9510
9511         /* Invalid objects. */
9512         while (gl.isRenderbuffer(++m_rbo_invalid))
9513                 ;
9514 }
9515
9516 /** Check if error is equal to the expected, log if not.
9517  *
9518  *  @param [in] expected_error      Error to be expected.
9519  *  @param [in] function            Function name which is being tested (to be logged).
9520  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
9521  *
9522  *  @return True if there is no error, false otherwise.
9523  */
9524 bool StorageMultisampleErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
9525                                                                                            const glw::GLchar* conditions)
9526 {
9527         /* Shortcut for GL functionality. */
9528         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9529
9530         bool is_ok = true;
9531
9532         glw::GLenum error = GL_NO_ERROR;
9533
9534         if (expected_error != (error = gl.getError()))
9535         {
9536                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
9537                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
9538                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
9539
9540                 is_ok = false;
9541         }
9542
9543         /* Clean additional possible errors. */
9544         while (gl.getError())
9545                 ;
9546
9547         return is_ok;
9548 }
9549
9550 /** @brief Clean up GL state.
9551  */
9552 void StorageMultisampleErrorsTest::Clean()
9553 {
9554         /* Shortcut for GL functionality. */
9555         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9556
9557         /* Release GL objects. */
9558         if (m_rbo_valid)
9559         {
9560                 gl.deleteRenderbuffers(1, &m_rbo_valid);
9561                 m_rbo_valid = 0;
9562         }
9563
9564         /*  COmpressed internal formats are not color renderable (OpenGL 4.5 Core PRofile SPecification Chapter 9.4 )*/
9565         m_internalformat_invalid = GL_COMPRESSED_RED;
9566
9567         /* Set initial values - all test shall have the same environment. */
9568         m_rbo_valid                       = 0;
9569         m_rbo_invalid             = 0;
9570         m_max_samples             = 0;
9571         m_max_integer_samples = 0;
9572
9573         /* Errors clean up. */
9574         while (gl.getError())
9575                 ;
9576 }
9577
9578 /******************************** Get Parameter Errors Test Implementation   ********************************/
9579
9580 /** @brief Parameter Errors Test constructor.
9581  *
9582  *  @param [in] context     OpenGL context.
9583  */
9584 GetParameterErrorsTest::GetParameterErrorsTest(deqp::Context& context)
9585         : deqp::TestCase(context, "renderbuffers_get_parameters_errors", "Get Parameter Errors Test")
9586         , m_rbo_valid(0)
9587         , m_rbo_invalid(0)
9588         , m_parameter_invalid(0)
9589 {
9590         /* Intentionally left blank. */
9591 }
9592
9593 /** @brief Iterate Parameter Errors Test cases.
9594  *
9595  *  @return Iteration result.
9596  */
9597 tcu::TestNode::IterateResult GetParameterErrorsTest::iterate()
9598 {
9599         /* Shortcut for GL functionality. */
9600         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9601
9602         /* Get context setup. */
9603         bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
9604         bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
9605
9606         if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
9607         {
9608                 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
9609
9610                 return STOP;
9611         }
9612
9613         /* Running tests. */
9614         bool is_ok      = true;
9615         bool is_error = false;
9616
9617         try
9618         {
9619                 /* Prepare objects. */
9620                 PrepareObjects();
9621
9622                 glw::GLint return_value_dummy_storage;
9623
9624                 /*  Check that INVALID_OPERATION is generated by
9625                  GetNamedRenderbufferParameteriv if renderbuffer is not the name of an
9626                  existing renderbuffer object. */
9627                 gl.getNamedRenderbufferParameteriv(m_rbo_invalid, GL_RENDERBUFFER_WIDTH, &return_value_dummy_storage);
9628
9629                 is_ok &= ExpectError(GL_INVALID_OPERATION, "GetNamedRenderbufferParameteriv",
9630                                                          "renderbuffer is not the name of an existing renderbuffer object.");
9631
9632                 /*  Check that INVALID_ENUM is generated by GetNamedRenderbufferParameteriv
9633                  if parameter name is not one of the accepted parameter names described
9634                  in specification. */
9635                 gl.getNamedRenderbufferParameteriv(m_rbo_valid, m_parameter_invalid, &return_value_dummy_storage);
9636
9637                 is_ok &= ExpectError(GL_INVALID_ENUM, "GetNamedRenderbufferParameteriv",
9638                                                          "parameter name is not one of the accepted parameter names described in specification.");
9639         }
9640         catch (...)
9641         {
9642                 is_ok   = false;
9643                 is_error = true;
9644         }
9645
9646         /* Cleanup. */
9647         Clean();
9648
9649         /* Result's setup. */
9650         if (is_ok)
9651         {
9652                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
9653         }
9654         else
9655         {
9656                 if (is_error)
9657                 {
9658                         m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
9659                 }
9660                 else
9661                 {
9662                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
9663                 }
9664         }
9665
9666         return STOP;
9667 }
9668
9669 /** Check Prepare test's GL objects.
9670  */
9671 void GetParameterErrorsTest::PrepareObjects()
9672 {
9673         /* Shortcut for GL functionality. */
9674         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9675
9676         /* Valid objects. */
9677         gl.genRenderbuffers(1, &m_rbo_valid);
9678         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers has failed");
9679
9680         gl.bindRenderbuffer(GL_RENDERBUFFER, m_rbo_valid);
9681         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer has failed");
9682
9683         /* Invalid parameter. */
9684         bool is_parameter = true;
9685
9686         while (is_parameter)
9687         {
9688                 is_parameter = false;
9689
9690                 ++m_parameter_invalid;
9691
9692                 static const glw::GLenum valid_parameters[] = { GL_RENDERBUFFER_WIDTH,                   GL_RENDERBUFFER_HEIGHT,
9693                                                                                                                 GL_RENDERBUFFER_INTERNAL_FORMAT, GL_RENDERBUFFER_SAMPLES,
9694                                                                                                                 GL_RENDERBUFFER_RED_SIZE,                GL_RENDERBUFFER_GREEN_SIZE,
9695                                                                                                                 GL_RENDERBUFFER_BLUE_SIZE,               GL_RENDERBUFFER_ALPHA_SIZE,
9696                                                                                                                 GL_RENDERBUFFER_DEPTH_SIZE,              GL_RENDERBUFFER_STENCIL_SIZE };
9697
9698                 static const glw::GLuint valid_parameters_count = sizeof(valid_parameters) / sizeof(valid_parameters[0]);
9699
9700                 for (glw::GLuint i = 0; i < valid_parameters_count; ++i)
9701                 {
9702                         if (valid_parameters[i] == m_parameter_invalid)
9703                         {
9704                                 is_parameter = true;
9705                         }
9706                 }
9707         }
9708
9709         /* Invalid objects. */
9710         while (gl.isRenderbuffer(++m_rbo_invalid))
9711                 ;
9712 }
9713
9714 /** Check if error is equal to the expected, log if not.
9715  *
9716  *  @param [in] expected_error      Error to be expected.
9717  *  @param [in] function            Function name which is being tested (to be logged).
9718  *  @param [in] conditions          Conditions when the expected error shall occure (to be logged).
9719  *
9720  *  @return True if there is no error, false otherwise.
9721  */
9722 bool GetParameterErrorsTest::ExpectError(glw::GLenum expected_error, const glw::GLchar* function,
9723                                                                                  const glw::GLchar* conditions)
9724 {
9725         /* Shortcut for GL functionality. */
9726         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9727
9728         bool is_ok = true;
9729
9730         glw::GLenum error = GL_NO_ERROR;
9731
9732         if (expected_error != (error = gl.getError()))
9733         {
9734                 m_context.getTestContext().getLog() << tcu::TestLog::Message << function << " was expected to generate "
9735                                                                                         << glu::getErrorStr(expected_error) << ", but " << glu::getErrorStr(error)
9736                                                                                         << " was observed instead when " << conditions << tcu::TestLog::EndMessage;
9737
9738                 is_ok = false;
9739         }
9740
9741         /* Clean additional possible errors. */
9742         while (gl.getError())
9743                 ;
9744
9745         return is_ok;
9746 }
9747
9748 /** @brief Clean up GL state.
9749  */
9750 void GetParameterErrorsTest::Clean()
9751 {
9752         /* Shortcut for GL functionality. */
9753         const glw::Functions& gl = m_context.getRenderContext().getFunctions();
9754
9755         /* Release GL objects. */
9756         if (m_rbo_valid)
9757         {
9758                 gl.deleteRenderbuffers(1, &m_rbo_valid);
9759                 m_rbo_valid = 0;
9760         }
9761
9762         /* Set initial values - all test shall have the same environment. */
9763         m_rbo_valid   = 0;
9764         m_rbo_invalid = 0;
9765
9766         /* Errors clean up. */
9767         while (gl.getError())
9768                 ;
9769 }
9770
9771 } // namespace Renderbuffers
9772 } // namespace DirectStateAccess
9773 } // namespace gl4cts