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