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