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