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