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