• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-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  es31cTextureStorageMultisampleDependenciesTests.cpp
27  * \brief Implements conformance tests that verify dependencies of
28  *        multisample textures on other parts of core ES3.1 API
29  *        (ES3.1 only)
30  */ /*-------------------------------------------------------------------*/
31 
32 #include "es31cTextureStorageMultisampleDependenciesTests.hpp"
33 #include "gluContextInfo.hpp"
34 #include "gluDefs.hpp"
35 #include "glwEnums.hpp"
36 #include "glwFunctions.hpp"
37 #include "tcuRenderTarget.hpp"
38 #include "tcuTestLog.hpp"
39 
40 #include <cmath>
41 #include <memory.h>
42 #include <string>
43 #include <vector>
44 
45 namespace glcts
46 {
47 /** Constructor.
48  *
49  *  @param context CTS context handle.
50  **/
MultisampleTextureDependenciesFBOIncompleteness1Test(Context & context)51 MultisampleTextureDependenciesFBOIncompleteness1Test::MultisampleTextureDependenciesFBOIncompleteness1Test(
52 	Context& context)
53 	: TestCase(context, "fbo_with_attachments_of_varying_amount_of_samples",
54 			   "FBOs with multisample texture attachments, whose amount"
55 			   " of samples differs between attachments, should be "
56 			   "considered incomplete")
57 	, fbo_id(0)
58 	, to_id_multisample_2d_array(0)
59 {
60 	memset(to_ids_multisample_2d, 0, sizeof(to_ids_multisample_2d));
61 }
62 
63 /** Deinitializes ES objects created during test execution */
deinit()64 void MultisampleTextureDependenciesFBOIncompleteness1Test::deinit()
65 {
66 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
67 
68 	if (fbo_id != 0)
69 	{
70 		gl.deleteFramebuffers(1, &fbo_id);
71 
72 		fbo_id = 0;
73 	}
74 
75 	if (to_ids_multisample_2d[0] != 0)
76 	{
77 		gl.deleteTextures(1, to_ids_multisample_2d + 0);
78 
79 		to_ids_multisample_2d[0] = 0;
80 	}
81 
82 	if (to_ids_multisample_2d[1] != 0)
83 	{
84 		gl.deleteTextures(1, to_ids_multisample_2d + 1);
85 
86 		to_ids_multisample_2d[1] = 0;
87 	}
88 
89 	if (to_id_multisample_2d_array != 0)
90 	{
91 		gl.deleteTextures(1, &to_id_multisample_2d_array);
92 
93 		to_id_multisample_2d_array = 0;
94 	}
95 
96 	/* Call base class' deinit() */
97 	TestCase::deinit();
98 }
99 
100 /** Executes test iteration.
101  *
102  *  @return Returns STOP when test has finished executing.
103  */
iterate()104 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness1Test::iterate()
105 {
106 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
107 	bool				  are_2d_ms_array_tos_supported =
108 		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
109 
110 	/* Set up texture objects */
111 	gl.genTextures(1, to_ids_multisample_2d);
112 
113 	if (are_2d_ms_array_tos_supported)
114 	{
115 		gl.genTextures(1, &to_id_multisample_2d_array);
116 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
117 	}
118 	else
119 	{
120 		gl.genTextures(1, to_ids_multisample_2d + 1);
121 	}
122 
123 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture objects");
124 
125 	/* Query possible sample count values for both texture targets
126 	 and format used in test */
127 	glw::GLint num_sample_counts_2dms   = 1;
128 	glw::GLint num_sample_counts_2dms_a = 1;
129 
130 	gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &num_sample_counts_2dms);
131 
132 	if (are_2d_ms_array_tos_supported)
133 	{
134 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1,
135 							   &num_sample_counts_2dms_a);
136 	}
137 
138 	std::vector<glw::GLint> sample_counts_2dms(num_sample_counts_2dms);
139 	std::vector<glw::GLint> sample_counts_2dms_a(num_sample_counts_2dms_a);
140 
141 	gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, num_sample_counts_2dms,
142 						   &sample_counts_2dms[0]);
143 
144 	if (are_2d_ms_array_tos_supported)
145 	{
146 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_RGBA8, GL_SAMPLES, num_sample_counts_2dms_a,
147 							   &sample_counts_2dms_a[0]);
148 	}
149 
150 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set query internal formats");
151 
152 	/* This will store actual sample counts to be used in test */
153 	glw::GLint samples_attachment_1 = 0;
154 	glw::GLint samples_attachment_2 = 0;
155 
156 	/* Choose two different sample counts, supported by implementation */
157 	if (are_2d_ms_array_tos_supported)
158 	{
159 		for (glw::GLint i_2dms = 0; i_2dms < num_sample_counts_2dms; i_2dms++)
160 		{
161 			for (glw::GLint i_2dms_a = 0; i_2dms_a < num_sample_counts_2dms_a; i_2dms_a++)
162 			{
163 				if (sample_counts_2dms[i_2dms] != sample_counts_2dms_a[i_2dms_a] && sample_counts_2dms[i_2dms] != 1 &&
164 					sample_counts_2dms_a[i_2dms_a] != 1)
165 				{
166 					/* found two differing non-1 sample counts ! */
167 					samples_attachment_1 = sample_counts_2dms[i_2dms];
168 					samples_attachment_2 = sample_counts_2dms_a[i_2dms_a];
169 				}
170 			}
171 		}
172 	} /* if (are_2d_ms_array_tos_supported) */
173 	else
174 	{
175 		for (glw::GLuint index = 1; index < sample_counts_2dms.size(); ++index)
176 		{
177 			if (sample_counts_2dms[index - 1] != 1 && sample_counts_2dms[index] != 1 &&
178 				sample_counts_2dms[index - 1] != sample_counts_2dms[index])
179 			{
180 				samples_attachment_1 = sample_counts_2dms[index - 1];
181 				samples_attachment_2 = sample_counts_2dms[index];
182 
183 				break;
184 			}
185 		}
186 	}
187 
188 	if (samples_attachment_1 == 0 || samples_attachment_2 == 0)
189 	{
190 		/* It may be the case implementation support only one
191 		 sample count on both targets with used format.
192 
193 		 In such case cannot perform the test - cannot make
194 		 FBO incomplete due to sample count mismatch
195 		 */
196 		m_testCtx.setTestResult(
197 			QP_TEST_RESULT_NOT_SUPPORTED,
198 			"Can't test incomplete FBO due to mismatch sample count: only 1 sample count available");
199 
200 		return STOP;
201 	}
202 
203 	for (int n_texture_2d = 0; n_texture_2d < (are_2d_ms_array_tos_supported ? 1 : 2); ++n_texture_2d)
204 	{
205 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_ids_multisample_2d[n_texture_2d]);
206 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
207 
208 		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE,
209 								   (n_texture_2d == 0) ? samples_attachment_1 : samples_attachment_2, GL_RGBA8,
210 								   2,		  /* width */
211 								   2,		  /* height */
212 								   GL_FALSE); /* fixedsamplelocations */
213 
214 		GLU_EXPECT_NO_ERROR(gl.getError(),
215 							"glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
216 	}
217 
218 	if (are_2d_ms_array_tos_supported)
219 	{
220 		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samples_attachment_2, /* samples */
221 								   GL_RGBA8, 2,												  /* width */
222 								   2,														  /* height */
223 								   2,														  /* depth */
224 								   GL_FALSE);												  /* fixedsamplelocations */
225 
226 		GLU_EXPECT_NO_ERROR(
227 			gl.getError(),
228 			"gltexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES texture target");
229 	}
230 
231 	/* Set up a framebuffer object */
232 	gl.genFramebuffers(1, &fbo_id);
233 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
234 
235 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
236 
237 	/* Set up FBO attachments */
238 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
239 							to_ids_multisample_2d[0], 0); /* level */
240 
241 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up zeroth color attachment");
242 
243 	if (are_2d_ms_array_tos_supported)
244 	{
245 		gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_multisample_2d_array, 0, /* level */
246 								   0);																		 /* layer */
247 	}
248 	else
249 	{
250 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
251 								to_ids_multisample_2d[1], 0); /* level */
252 	}
253 
254 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up first color attachment");
255 
256 	/* Make sure the draw framebuffer is considered incomplete */
257 	glw::GLenum fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
258 
259 	if (fbo_status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
260 	{
261 		m_testCtx.getLog() << tcu::TestLog::Message << "Draw framebuffer's completeness status is: " << fbo_status
262 						   << "as opposed to expected status: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"
263 						   << tcu::TestLog::EndMessage;
264 
265 		TCU_FAIL("Invalid FBO completeness status reported.");
266 	}
267 
268 	/* All done */
269 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
270 
271 	return STOP;
272 }
273 
274 /** Constructor.
275  *
276  *  @param context CTS context handle.
277  **/
MultisampleTextureDependenciesFBOIncompleteness2Test(Context & context)278 MultisampleTextureDependenciesFBOIncompleteness2Test::MultisampleTextureDependenciesFBOIncompleteness2Test(
279 	Context& context)
280 	: TestCase(context, "fbo_with_single_and_multisample_attachments",
281 			   "FBOs with multisample texture and normal 2D texture attachments "
282 			   "should be considered incomplete")
283 	, fbo_id(0)
284 	, to_id_2d(0)
285 	, to_id_multisample_2d(0)
286 	, to_id_multisample_2d_array(0)
287 {
288 	/* Left blank on purpose */
289 }
290 
291 /** Deinitializes ES objects created during test execution */
deinit()292 void MultisampleTextureDependenciesFBOIncompleteness2Test::deinit()
293 {
294 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
295 
296 	if (fbo_id != 0)
297 	{
298 		gl.deleteFramebuffers(1, &fbo_id);
299 
300 		fbo_id = 0;
301 	}
302 
303 	if (to_id_2d != 0)
304 	{
305 		gl.deleteTextures(1, &to_id_2d);
306 
307 		to_id_2d = 0;
308 	}
309 
310 	if (to_id_multisample_2d != 0)
311 	{
312 		gl.deleteTextures(1, &to_id_multisample_2d);
313 
314 		to_id_multisample_2d = 0;
315 	}
316 
317 	if (to_id_multisample_2d_array != 0)
318 	{
319 		gl.deleteTextures(1, &to_id_multisample_2d_array);
320 
321 		to_id_multisample_2d_array = 0;
322 	}
323 
324 	/* Call base class' deinit() */
325 	TestCase::deinit();
326 }
327 
328 /** Executes test iteration.
329  *
330  *  @return Returns STOP when test has finished executing.
331  */
iterate()332 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness2Test::iterate()
333 {
334 	bool are_2d_ms_array_tos_supported =
335 		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
336 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
337 
338 	/* Set up texture objects */
339 	gl.genTextures(1, &to_id_2d);
340 	gl.genTextures(1, &to_id_multisample_2d);
341 
342 	if (are_2d_ms_array_tos_supported)
343 	{
344 		gl.genTextures(1, &to_id_multisample_2d_array);
345 	}
346 
347 	gl.bindTexture(GL_TEXTURE_2D, to_id_2d);
348 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d);
349 
350 	if (are_2d_ms_array_tos_supported)
351 	{
352 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
353 	}
354 
355 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture objects");
356 
357 	gl.texImage2D(GL_TEXTURE_2D, 0, /* level */
358 				  GL_RGB565, 2,		/* width */
359 				  2,				/* height */
360 				  0,				/* border */
361 				  GL_RGB,			/* format */
362 				  GL_UNSIGNED_BYTE, /* type */
363 				  NULL);			/* pixels */
364 
365 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() call failed for GL_TEXTURE_2D texture target");
366 
367 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
368 							   GL_RGB565, 2,				 /* width */
369 							   2,							 /* height */
370 							   GL_FALSE);					 /* fixedsamplelocations */
371 
372 	GLU_EXPECT_NO_ERROR(gl.getError(),
373 						"glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
374 
375 	if (are_2d_ms_array_tos_supported)
376 	{
377 		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, /* samples */
378 								   GL_RGB565, 2,						   /* width */
379 								   2,									   /* height */
380 								   2,									   /* depth */
381 								   GL_FALSE);							   /* fixedsamplelocations */
382 
383 		GLU_EXPECT_NO_ERROR(
384 			gl.getError(),
385 			"gltexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES texture target");
386 	}
387 
388 	/* Set up a framebuffer object */
389 	gl.genFramebuffers(1, &fbo_id);
390 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
391 
392 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
393 
394 	/* Set up FBO attachments */
395 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, to_id_2d, 0); /* level */
396 
397 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up zeroth color attachment");
398 
399 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d,
400 							0); /* level */
401 
402 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up first color attachment");
403 
404 	/* Make sure the draw framebuffer is considered incomplete */
405 	glw::GLenum fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
406 
407 	if (fbo_status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
408 	{
409 		m_testCtx.getLog() << tcu::TestLog::Message << "Draw framebuffer's completeness status is: " << fbo_status
410 						   << "as opposed to expected status: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"
411 						   << tcu::TestLog::EndMessage;
412 
413 		TCU_FAIL("Invalid FBO completeness status reported.");
414 	}
415 
416 	/* Detach the first color attachment */
417 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE, 0, /* texture */
418 							0);																		 /* level */
419 
420 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not detach first color attachment from the draw FBO");
421 
422 	/* Verify the FBO is now considered complete */
423 	fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
424 
425 	if (fbo_status != GL_FRAMEBUFFER_COMPLETE)
426 	{
427 		m_testCtx.getLog() << tcu::TestLog::Message << "Draw framebuffer's completeness status is: " << fbo_status
428 						   << "as opposed to expected status: GL_FRAMEBUFFER_COMPLETE" << tcu::TestLog::EndMessage;
429 
430 		TCU_FAIL("Invalid FBO completeness status reported.");
431 	}
432 
433 	if (are_2d_ms_array_tos_supported)
434 	{
435 		/* Attach the arrayed multisample texture object */
436 		gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_multisample_2d_array, 0, /* level */
437 								   0);																		 /* layer */
438 
439 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up first color attachment");
440 
441 		/* Make sure the draw framebuffer is considered incomplete */
442 		fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
443 
444 		if (fbo_status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
445 		{
446 			m_testCtx.getLog() << tcu::TestLog::Message << "Draw framebuffer's completeness status is: " << fbo_status
447 							   << "as opposed to expected status: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"
448 							   << tcu::TestLog::EndMessage;
449 
450 			TCU_FAIL("Invalid FBO completeness status reported.");
451 		}
452 	}
453 
454 	/* All done */
455 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
456 
457 	return STOP;
458 }
459 
460 /** Constructor.
461  *
462  *  @param context CTS context handle.
463  **/
MultisampleTextureDependenciesFBOIncompleteness3Test(Context & context)464 MultisampleTextureDependenciesFBOIncompleteness3Test::MultisampleTextureDependenciesFBOIncompleteness3Test(
465 	Context& context)
466 	: TestCase(context, "fbo_with_fixed_and_varying_sample_locations_attachments",
467 			   "FBOs with multisample texture attachments of different fixed "
468 			   "sample location settings should be considered incomplete")
469 	, fbo_id(0)
470 	, to_id_2d_multisample_color_1(0)
471 	, to_id_2d_multisample_color_2(0)
472 	, to_id_2d_multisample_depth(0)
473 	, to_id_2d_multisample_depth_stencil(0)
474 {
475 	/* Left blank on purpose */
476 }
477 
478 /** Deinitializes ES objects created during test execution */
deinit()479 void MultisampleTextureDependenciesFBOIncompleteness3Test::deinit()
480 {
481 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
482 
483 	if (fbo_id != 0)
484 	{
485 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
486 		gl.deleteFramebuffers(1, &fbo_id);
487 
488 		fbo_id = 0;
489 	}
490 
491 	if (to_id_2d_multisample_color_1 != 0)
492 	{
493 		gl.deleteTextures(1, &to_id_2d_multisample_color_1);
494 
495 		to_id_2d_multisample_color_1 = 0;
496 	}
497 
498 	if (to_id_2d_multisample_color_2 != 0)
499 	{
500 		gl.deleteTextures(1, &to_id_2d_multisample_color_2);
501 
502 		to_id_2d_multisample_color_2 = 0;
503 	}
504 
505 	if (to_id_2d_multisample_depth != 0)
506 	{
507 		gl.deleteTextures(1, &to_id_2d_multisample_depth);
508 
509 		to_id_2d_multisample_depth = 0;
510 	}
511 
512 	if (to_id_2d_multisample_depth_stencil != 0)
513 	{
514 		gl.deleteTextures(1, &to_id_2d_multisample_depth_stencil);
515 
516 		to_id_2d_multisample_depth_stencil = 0;
517 	}
518 
519 	/* Call base class' deinit() */
520 	TestCase::deinit();
521 }
522 
523 /** Executes test iteration.
524  *
525  *  @return Returns STOP when test has finished executing.
526  */
iterate()527 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness3Test::iterate()
528 {
529 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
530 
531 	/* Only execute if GL_MAX_SAMPLES pname value >= 2 */
532 	glw::GLint gl_max_samples_value = 0;
533 
534 	gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
535 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() generated an error for GL_MAX_SAMPLES pname");
536 
537 	if (gl_max_samples_value < 2)
538 	{
539 		throw tcu::NotSupportedError("GL_MAX_SAMPLES pname value < 2, skipping");
540 	}
541 
542 	/* Only execute if GL_RGBA8, GL_DEPTH_COMPONENT16, GL_DEPTH24_STENCIL8 internalformats
543 	 * can be rendered to with at least 2 samples per fragment.
544 	 */
545 	glw::GLint depth_component16_internalformat_max_samples = 0;
546 	glw::GLint depth24_stencil8_internalformat_max_samples  = 0;
547 	glw::GLint rgba8_internalformat_max_samples				= 0;
548 
549 	gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_DEPTH_COMPONENT16, GL_SAMPLES, 1, /* bufSize */
550 						   &depth_component16_internalformat_max_samples);
551 	gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_DEPTH24_STENCIL8, GL_SAMPLES, 1, /* bufSize */
552 						   &depth24_stencil8_internalformat_max_samples);
553 	gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, 1, /* bufSize */
554 						   &rgba8_internalformat_max_samples);
555 
556 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed for at least one GL_SAMPLES query");
557 
558 	if (depth_component16_internalformat_max_samples < 2)
559 	{
560 		throw tcu::NotSupportedError("GL_SAMPLES is lower than 2 for GL_DEPTH_COMPONENT16 internalformat");
561 	}
562 
563 	if (depth24_stencil8_internalformat_max_samples < 2)
564 	{
565 		throw tcu::NotSupportedError("GL_SAMPLES is lower than 2 for GL_DEPTH24_STENCIL8 internalformat");
566 	}
567 
568 	if (rgba8_internalformat_max_samples < 2)
569 	{
570 		throw tcu::NotSupportedError("GL_SAMPLES is lower than 2 for GL_RGBA8 internalformat");
571 	}
572 
573 	/* Set up texture objects */
574 	gl.genTextures(1, &to_id_2d_multisample_color_1);
575 	gl.genTextures(1, &to_id_2d_multisample_color_2);
576 	gl.genTextures(1, &to_id_2d_multisample_depth);
577 	gl.genTextures(1, &to_id_2d_multisample_depth_stencil);
578 
579 	GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed");
580 
581 	/* Set up a framebuffer object */
582 	gl.genFramebuffers(1, &fbo_id);
583 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
584 
585 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
586 
587 	/* Set up first GL_RGBA8 multisample texture storage */
588 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_color_1);
589 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
590 							   GL_RGBA8, 2,					 /* width */
591 							   2,							 /* height */
592 							   GL_FALSE);					 /* fixedsamplelocations */
593 
594 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up first GL_RGBA8 multisample texture storage.");
595 
596 	/* Set up second GL_RGBA8 multisample texture storage */
597 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_color_2);
598 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
599 							   GL_RGBA8, 2,					 /* width */
600 							   2,							 /* height */
601 							   GL_TRUE);					 /* fixedsamplelocations */
602 
603 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up second GL_RGBA8 multisample texture storage.");
604 
605 	/* Set up GL_DEPTH_COMPONENT16 multisample texture storage */
606 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_depth);
607 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
608 							   GL_DEPTH_COMPONENT16, 2,		 /* width */
609 							   2,							 /* height */
610 							   GL_TRUE);					 /* fixedsamplelocations */
611 
612 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up GL_DEPTH_COMPONENT16 multisample texture storage.");
613 
614 	/* Set up GL_DEPTH24_STENCIL8 multisample texture storage */
615 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_depth_stencil);
616 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
617 							   GL_DEPTH24_STENCIL8, 2,		 /* width */
618 							   2,							 /* height */
619 							   GL_TRUE);					 /* fixedsamplelocations */
620 
621 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up GL_DEPTH24_STENCIL8 multisample texture storage.");
622 
623 	/* Set up FBO's zeroth color attachment */
624 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
625 							to_id_2d_multisample_color_1, 0); /* level */
626 
627 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
628 							to_id_2d_multisample_color_2, 0); /* level */
629 
630 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up FBO color attachments");
631 
632 	/* FBO should now be considered incomplete */
633 	glw::GLenum fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
634 
635 	if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
636 	{
637 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
638 						   << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
639 
640 		TCU_FAIL("Invalid FBO completeness status reported.");
641 	}
642 
643 	/* Detach the first color attachment */
644 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, /* texture */
645 							0);															 /* level */
646 
647 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not detach FBO's first color attachment");
648 
649 	/* Configure FBO's depth attachment */
650 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
651 							to_id_2d_multisample_depth, 0); /* level */
652 
653 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not configure FBO's depth attachment");
654 
655 	/* FBO should now be considered incomplete */
656 	fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
657 
658 	if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
659 	{
660 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
661 						   << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
662 
663 		TCU_FAIL("Invalid FBO completeness status reported.");
664 	}
665 
666 	/* Detach depth attachment */
667 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, /* texture */
668 							0);															/* level */
669 
670 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not detach FBO's depth attachment");
671 
672 	/* Configure FBO's depth+stencil attachment */
673 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE,
674 							to_id_2d_multisample_depth_stencil, 0); /* level */
675 
676 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not configure FBO's depth+stencil attachment");
677 
678 	/* FBO should now be considered incomplete */
679 	fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
680 
681 	if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
682 	{
683 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
684 						   << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
685 
686 		TCU_FAIL("Invalid FBO completeness status reported.");
687 	}
688 
689 	/* All done */
690 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
691 
692 	return STOP;
693 }
694 
695 /** Constructor.
696  *
697  *  @param context CTS context handle.
698  **/
MultisampleTextureDependenciesFBOIncompleteness4Test(Context & context)699 MultisampleTextureDependenciesFBOIncompleteness4Test::MultisampleTextureDependenciesFBOIncompleteness4Test(
700 	Context& context)
701 	: TestCase(context, "fbo_with_different_fixedsamplelocations_texture_and_renderbuffer_attachments",
702 			   "FBOs with multisample texture attachments of different 'fixed sample location' "
703 			   "settings and with multisampled renderbuffers (of the same amount of samples)"
704 			   "should be considered incomplete")
705 	, fbo_id(0)
706 	, rbo_id(0)
707 	, to_id_2d_multisample_array_color(0)
708 	, to_id_2d_multisample_color(0)
709 {
710 	/* Left blank on purpose */
711 }
712 
713 /** Deinitializes ES objects created during test execution */
deinit()714 void MultisampleTextureDependenciesFBOIncompleteness4Test::deinit()
715 {
716 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
717 
718 	if (fbo_id != 0)
719 	{
720 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
721 		gl.deleteFramebuffers(1, &fbo_id);
722 
723 		fbo_id = 0;
724 	}
725 
726 	if (rbo_id != 0)
727 	{
728 		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
729 		gl.deleteRenderbuffers(1, &rbo_id);
730 	}
731 
732 	if (to_id_2d_multisample_color != 0)
733 	{
734 		gl.deleteTextures(1, &to_id_2d_multisample_color);
735 
736 		to_id_2d_multisample_color = 0;
737 	}
738 
739 	if (to_id_2d_multisample_array_color != 0)
740 	{
741 		gl.deleteTextures(1, &to_id_2d_multisample_array_color);
742 
743 		to_id_2d_multisample_array_color = 0;
744 	}
745 
746 	/* Call base class' deinit() */
747 	TestCase::deinit();
748 }
749 
750 /** Executes test iteration.
751  *
752  *  @return Returns STOP when test has finished executing.
753  */
iterate()754 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness4Test::iterate()
755 {
756 	bool are_2d_ms_array_tos_supported =
757 		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
758 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
759 
760 	/* Only execute if GL_MAX_SAMPLES pname value >= 3 */
761 	glw::GLint gl_max_samples_value = 0;
762 
763 	gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
764 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() generated an error for GL_MAX_SAMPLES pname");
765 
766 	if (gl_max_samples_value < 3)
767 	{
768 		throw tcu::NotSupportedError("GL_MAX_SAMPLES pname value < 3, skipping");
769 	}
770 
771 	/* Set up texture objects */
772 	if (are_2d_ms_array_tos_supported)
773 	{
774 		gl.genTextures(1, &to_id_2d_multisample_array_color);
775 	}
776 
777 	gl.genTextures(1, &to_id_2d_multisample_color);
778 
779 	GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed");
780 
781 	/* Set up a framebuffer object */
782 	gl.genFramebuffers(1, &fbo_id);
783 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
784 
785 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
786 
787 	/* Set up a renderbuffer object */
788 	gl.genRenderbuffers(1, &rbo_id);
789 	gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
790 
791 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
792 
793 	/* Set up first GL_RGBA8 multisample texture storage */
794 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample_color);
795 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
796 							   GL_RGBA8, 2,					 /* width */
797 							   2,							 /* height */
798 							   GL_FALSE);					 /* fixedsamplelocations */
799 
800 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up GL_RGBA8 multisample texture storage.");
801 
802 	if (are_2d_ms_array_tos_supported)
803 	{
804 		/* Set up second GL_RGBA8 multisample texture storage */
805 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_2d_multisample_array_color);
806 		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, /* samples */
807 								   GL_RGBA8, 2,							   /* width */
808 								   2,									   /* height */
809 								   2,									   /* depth */
810 								   GL_TRUE);							   /* fixedsamplelocations */
811 
812 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up second GL_RGBA8 multisample texture storage.");
813 	}
814 
815 	/* Set up renderbuffer storage */
816 	gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 3, /* samples */
817 									  GL_RGBA8, 2,		  /* width */
818 									  2);				  /* height */
819 
820 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up renderbuffer storage.");
821 
822 	/* Set up FBO's zeroth color attachment */
823 	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
824 							to_id_2d_multisample_color, 0); /* level */
825 
826 	/* Make sure FBO is considered complete at this point */
827 	glw::GLenum fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
828 
829 	if (fbo_completeness != GL_FRAMEBUFFER_COMPLETE)
830 	{
831 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
832 						   << " expected: GL_FRAMEBUFFER_COMPLETE" << tcu::TestLog::EndMessage;
833 
834 		TCU_FAIL("Invalid FBO completeness status reported.");
835 	}
836 
837 	if (are_2d_ms_array_tos_supported)
838 	{
839 		/* Set up FBO's first color attachment */
840 		gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_2d_multisample_array_color,
841 								   0,  /* level */
842 								   0); /* layer */
843 
844 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up FBO color attachments");
845 
846 		/* FBO should now be considered incomplete */
847 		fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
848 
849 		if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
850 		{
851 			m_testCtx.getLog() << tcu::TestLog::Message
852 							   << "Invalid FBO completeness status reported:" << fbo_completeness
853 							   << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
854 
855 			TCU_FAIL("Invalid FBO completeness status reported.");
856 		}
857 	}
858 
859 	/* Set up FBO's second color attachment */
860 	gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rbo_id);
861 
862 	/* FBO should now be considered incomplete */
863 	fbo_completeness = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
864 
865 	if (fbo_completeness != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
866 	{
867 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid FBO completeness status reported:" << fbo_completeness
868 						   << " expected: GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << tcu::TestLog::EndMessage;
869 
870 		TCU_FAIL("Invalid FBO completeness status reported.");
871 	}
872 
873 	/* All done */
874 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
875 
876 	return STOP;
877 }
878 
879 /** Constructor.
880  *
881  *  @param context CTS context handle.
882  **/
MultisampleTextureDependenciesFBOIncompleteness5Test(Context & context)883 MultisampleTextureDependenciesFBOIncompleteness5Test::MultisampleTextureDependenciesFBOIncompleteness5Test(
884 	Context& context)
885 	: TestCase(context, "fbo_with_renderbuffer_and_multisample_texture_attachments_with_different_number_of_samples",
886 			   "FBOs with renderbuffer and multisample texture attachments, where amount "
887 			   "of samples used for multisample texture attachments differs from the "
888 			   "amount of samples used for renderbuffer attachments, should be considered "
889 			   "incomplete")
890 	, fbo_id(0)
891 	, rbo_id(0)
892 	, to_id_multisample_2d(0)
893 	, to_id_multisample_2d_array(0)
894 {
895 	/* Left blank on purpose */
896 }
897 
898 /** Deinitializes ES objects created during test execution */
deinit()899 void MultisampleTextureDependenciesFBOIncompleteness5Test::deinit()
900 {
901 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
902 
903 	if (fbo_id != 0)
904 	{
905 		gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
906 		gl.deleteFramebuffers(1, &fbo_id);
907 
908 		fbo_id = 0;
909 	}
910 
911 	if (rbo_id != 0)
912 	{
913 		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
914 		gl.deleteRenderbuffers(1, &rbo_id);
915 	}
916 
917 	if (to_id_multisample_2d != 0)
918 	{
919 		gl.deleteTextures(1, &to_id_multisample_2d);
920 
921 		to_id_multisample_2d = 0;
922 	}
923 
924 	if (to_id_multisample_2d_array != 0)
925 	{
926 		gl.deleteTextures(1, &to_id_multisample_2d_array);
927 
928 		to_id_multisample_2d_array = 0;
929 	}
930 
931 	/* Call base class' deinit() */
932 	TestCase::deinit();
933 }
934 
935 /** Executes test iteration.
936  *
937  *  @return Returns STOP when test has finished executing.
938  */
iterate()939 tcu::TestNode::IterateResult MultisampleTextureDependenciesFBOIncompleteness5Test::iterate()
940 {
941 	bool are_multisample_2d_array_tos_supported =
942 		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
943 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
944 
945 	/* Retrieve GL_MAX_INTEGER_SAMPLES and GL_MAX_SAMPLES values */
946 	glw::GLint gl_max_integer_samples_value = 0;
947 	glw::GLint gl_max_samples_value			= 0;
948 
949 	gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &gl_max_integer_samples_value);
950 	gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
951 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() generated an error");
952 
953 	/* Set up texture objects */
954 	gl.genTextures(1, &to_id_multisample_2d);
955 
956 	if (are_multisample_2d_array_tos_supported)
957 	{
958 		gl.genTextures(1, &to_id_multisample_2d_array);
959 	}
960 
961 	GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed");
962 
963 	/* Set up a framebuffer object */
964 	gl.genFramebuffers(1, &fbo_id);
965 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
966 
967 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
968 
969 	/* Set up a renderbuffer object */
970 	gl.genRenderbuffers(1, &rbo_id);
971 	gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
972 
973 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
974 
975 	/* Bind texture objects to relevant texture targets */
976 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d);
977 
978 	if (are_multisample_2d_array_tos_supported)
979 	{
980 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
981 	}
982 
983 	GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glBindTexture() call failed.");
984 
985 	/* Iterate through internalformats. Current internalformat will be used
986 	 * by the 2D multisample attachment */
987 	const glw::GLenum  internalformats[] = { GL_R8, GL_RGB565, GL_RGB10_A2UI, GL_SRGB8_ALPHA8, GL_R8I };
988 	const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
989 
990 	for (unsigned int n_2d_multisample_internalformat = 0; n_2d_multisample_internalformat < n_internalformats;
991 		 ++n_2d_multisample_internalformat)
992 	{
993 		glw::GLenum internalformat_2d_multisample = internalformats[n_2d_multisample_internalformat];
994 
995 		/* Query sample counts supported for 2DMS texture on given internal format */
996 		glw::GLint num_sample_counts_2dms;
997 
998 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat_2d_multisample, GL_NUM_SAMPLE_COUNTS, 1,
999 							   &num_sample_counts_2dms);
1000 
1001 		std::vector<glw::GLint> sample_counts_2dms(num_sample_counts_2dms);
1002 
1003 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat_2d_multisample, GL_SAMPLES,
1004 							   num_sample_counts_2dms, &sample_counts_2dms[0]);
1005 
1006 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve sample counts supported for 2DMS");
1007 
1008 		/* Iterate again through the internalformats. This internalformat will be used
1009 		 * by the 2D multisample array attacmhent.
1010 		 *
1011 		 * NOTE: Under implementations which do not support 2DMS Array textures, we will
1012 		 *       not attach the 2DMS Array textures to the FBO at all. This fits the conformance
1013 		 *       test idea and does not break existing test implementation.
1014 		 *       However, since 2DMS Array textures are unavailable, we only run a single inner
1015 		 *       loop iteration. More iterations would not bring anything to the table at all.
1016 		 */
1017 		for (unsigned int n_2d_multisample_array_internalformat = 0;
1018 			 n_2d_multisample_array_internalformat < ((are_multisample_2d_array_tos_supported) ? n_internalformats : 1);
1019 			 ++n_2d_multisample_array_internalformat)
1020 		{
1021 			glw::GLenum internalformat_2d_multisample_array = internalformats[n_2d_multisample_array_internalformat];
1022 			glw::GLint  num_sample_counts_2dms_array		= 1;
1023 			std::vector<glw::GLint> sample_counts_2dms_array(num_sample_counts_2dms_array);
1024 
1025 			if (are_multisample_2d_array_tos_supported)
1026 			{
1027 				/* Query sample counts supported for 2DMS_ARRAY texture on given internal format */
1028 				gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, internalformat_2d_multisample_array,
1029 									   GL_NUM_SAMPLE_COUNTS, 1, &num_sample_counts_2dms_array);
1030 
1031 				sample_counts_2dms_array.resize(num_sample_counts_2dms_array);
1032 
1033 				gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, internalformat_2d_multisample_array,
1034 									   GL_SAMPLES, num_sample_counts_2dms_array, &sample_counts_2dms_array[0]);
1035 
1036 				GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve sample counts supported for 2DMS_ARRAY");
1037 			}
1038 			else
1039 			{
1040 				/* Add a single entry to the 2d ms sample count array */
1041 				num_sample_counts_2dms_array = 1;
1042 				sample_counts_2dms_array[0]  = 0;
1043 			}
1044 
1045 			/* One more iteration for renderbuffer attachment */
1046 			for (unsigned int n_rbo_internalformat = 0; n_rbo_internalformat < n_internalformats;
1047 				 ++n_rbo_internalformat)
1048 			{
1049 				glw::GLenum internalformat_rbo = internalformats[n_rbo_internalformat];
1050 
1051 				/* Query sample counts supported for RBO on given internal format */
1052 				glw::GLint num_sample_counts_rbo;
1053 
1054 				gl.getInternalformativ(GL_RENDERBUFFER, internalformat_rbo, GL_NUM_SAMPLE_COUNTS, 1,
1055 									   &num_sample_counts_rbo);
1056 
1057 				std::vector<glw::GLint> sample_counts_rbo(num_sample_counts_rbo);
1058 
1059 				gl.getInternalformativ(GL_RENDERBUFFER, internalformat_rbo, GL_SAMPLES, num_sample_counts_rbo,
1060 									   &sample_counts_rbo[0]);
1061 
1062 				GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve sample counts supported for rbo");
1063 
1064 				/* Now iterate over all samples argument we will use for the 2D multisample attachment */
1065 				for (int i_2dms = 0; i_2dms < num_sample_counts_2dms; ++i_2dms)
1066 				{
1067 					int samples_2d_multisample = sample_counts_2dms[i_2dms];
1068 
1069 					/* ..and yet another iteration for the 2D multisample array attachment */
1070 					for (int i_2dms_array = 0; i_2dms_array < num_sample_counts_2dms_array; ++i_2dms_array)
1071 					{
1072 						int samples_2d_multisample_array = sample_counts_2dms_array[i_2dms_array];
1073 
1074 						/* Finally, iterate over values to be used for samples argument of
1075 						 * a glRenderbufferStorageMultisample() call.
1076 						 */
1077 						for (int i_rbo = 0; i_rbo < num_sample_counts_rbo; ++i_rbo)
1078 						{
1079 							int samples_rbo = sample_counts_rbo[i_rbo];
1080 
1081 							/* This is a negative test. Hence, skip an iteration where all the
1082 							 * samples arguments used for the multisample 2d/multisample 2d array/rbo
1083 							 * triple match.
1084 							 */
1085 							if (((samples_rbo == samples_2d_multisample) &&
1086 								 (samples_rbo == samples_2d_multisample_array)) ||
1087 								(samples_rbo == 1) || (samples_2d_multisample == 1) ||
1088 								(samples_2d_multisample_array == 1))
1089 							{
1090 								/* Skip the iteration */
1091 								continue;
1092 							}
1093 
1094 							/* Set up 2D multisample texture storage. */
1095 							gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples_2d_multisample,
1096 													   internalformat_2d_multisample, 2, /* width */
1097 													   2,								 /* height */
1098 													   GL_FALSE);
1099 							GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed.");
1100 
1101 							if (are_multisample_2d_array_tos_supported)
1102 							{
1103 								/* Set up 2D multisample array texture storage. */
1104 								gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES,
1105 														   samples_2d_multisample_array,
1106 														   internalformat_2d_multisample_array, 2, /* width */
1107 														   2,									   /* height */
1108 														   2,									   /* depth */
1109 														   GL_FALSE);
1110 								GLU_EXPECT_NO_ERROR(gl.getError(), "gltexStorage3DMultisample() call failed.");
1111 							}
1112 
1113 							/* Set up renderbuffer storage */
1114 							gl.renderbufferStorageMultisample(GL_RENDERBUFFER, samples_rbo, internalformat_rbo,
1115 															  2,  /* width */
1116 															  2); /* height */
1117 							GLU_EXPECT_NO_ERROR(gl.getError(), "glRenderbufferStorageMultisample() call failed.");
1118 
1119 							/* Set up FBO's color attachments */
1120 							gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1121 													GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d, 0); /* level */
1122 							GLU_EXPECT_NO_ERROR(
1123 								gl.getError(),
1124 								"glFramebufferTexture2D() call failed for GL_COLOR_ATTACHMENT0 color attachment.");
1125 
1126 							if (are_multisample_2d_array_tos_supported)
1127 							{
1128 								gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
1129 														   to_id_multisample_2d_array, 0, /* level */
1130 														   0);							  /* layer */
1131 								GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed for "
1132 																   "GL_COLOR_ATTACHMENT1 color attachment.");
1133 							}
1134 
1135 							gl.framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER,
1136 													   rbo_id);
1137 							GLU_EXPECT_NO_ERROR(
1138 								gl.getError(),
1139 								"glFramebufferRenderbuffer() call failed for GL_COLOR_ATTACHMENT2 color attachment.");
1140 
1141 							/* Make sure the FBO is incomplete */
1142 							glw::GLenum fbo_completeness_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
1143 
1144 							if (fbo_completeness_status != GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE)
1145 							{
1146 								m_testCtx.getLog() << tcu::TestLog::Message
1147 												   << "Invalid FBO completeness status reported ["
1148 												   << fbo_completeness_status
1149 												   << "]"
1150 													  " instead of expected GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE."
1151 												   << " Sample count 2D_MS:" << samples_2d_multisample
1152 												   << " Sample count 2D_MS_ARRAY:" << samples_2d_multisample_array
1153 												   << " Sample count RBO:" << samples_rbo << tcu::TestLog::EndMessage;
1154 
1155 								TCU_FAIL("Invalid FBO completeness status reported.");
1156 							}
1157 
1158 							/* Re-create texture objects */
1159 							gl.deleteTextures(1, &to_id_multisample_2d);
1160 
1161 							if (are_multisample_2d_array_tos_supported)
1162 							{
1163 								gl.deleteTextures(1, &to_id_multisample_2d_array);
1164 							}
1165 
1166 							GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glDeleteTextures() call failed.");
1167 
1168 							gl.genTextures(1, &to_id_multisample_2d);
1169 
1170 							if (are_multisample_2d_array_tos_supported)
1171 							{
1172 								gl.genTextures(1, &to_id_multisample_2d_array);
1173 							}
1174 
1175 							GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed.");
1176 
1177 							gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d);
1178 
1179 							if (are_multisample_2d_array_tos_supported)
1180 							{
1181 								gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
1182 							}
1183 
1184 							GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glBindTexture() call failed.");
1185 						} /* for (all samples argument values to be used for renderbuffer attachment) */
1186 					}	 /* for (all samples argument values to be used for 2D multisample array attachment) */
1187 				}		  /* for (all samples argument values to be used for 2D multisample attachment) */
1188 			}			  /* for (all internalformats used by renderbuffer attachment) */
1189 		}				  /* for (all internalformats used by 2D multisample array attachment) */
1190 	}					  /* for (all internalformats used by 2D multisample attachment) */
1191 
1192 	/* All done */
1193 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1194 
1195 	return STOP;
1196 }
1197 
1198 /** Constructor.
1199  *
1200  *  @param context CTS context handle.
1201  **/
1202 MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test::
MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test(Context & context)1203 	MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test(Context& context)
1204 	: TestCase(context, "framebuffer_texture2d_used_with_invalid_texture_target",
1205 			   "Checks GL_INVALID_OPERATION is reported if 2D or cube-map texture "
1206 			   "target is used with a multisample 2D texture for a "
1207 			   "glFramebufferTexture2D() call")
1208 	, fbo_id(0)
1209 	, to_id(0)
1210 {
1211 	/* Left blank on purpose */
1212 }
1213 
1214 /** Deinitializes ES objects created during test execution */
deinit()1215 void MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test::deinit()
1216 {
1217 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1218 
1219 	if (fbo_id != 0)
1220 	{
1221 		gl.deleteFramebuffers(1, &fbo_id);
1222 
1223 		fbo_id = 0;
1224 	}
1225 
1226 	if (to_id != 0)
1227 	{
1228 		gl.deleteTextures(1, &to_id);
1229 
1230 		to_id = 0;
1231 	}
1232 
1233 	/* Call base class' deinit() */
1234 	TestCase::deinit();
1235 }
1236 
1237 /** Initializes ES objects created during test execution */
initInternals()1238 void MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test::initInternals()
1239 {
1240 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1241 
1242 	/* Generate and bind a framebuffer object */
1243 	gl.genFramebuffers(1, &fbo_id);
1244 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
1245 
1246 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
1247 
1248 	/* Generate and bind a texture object to GL_TEXTURE_2D_MULTISAMPLE texture target */
1249 	gl.genTextures(1, &to_id);
1250 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1251 
1252 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
1253 }
1254 
1255 /** Executes test iteration.
1256  *
1257  *  @return Returns STOP when test has finished executing.
1258  */
iterate()1259 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls1Test::iterate()
1260 {
1261 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1262 
1263 	initInternals();
1264 
1265 	/* For storing internalformat specific maximum number of samples */
1266 	glw::GLint gl_max_internalformat_samples = 0;
1267 
1268 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_INTEGER_SAMPLES and/or GL_MAX_SAMPLES values");
1269 
1270 	/* Iterate through all internalformats to be used for the test */
1271 	const glw::GLenum internalformats[] = {
1272 		GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I
1273 	};
1274 
1275 	const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
1276 
1277 	for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1278 	{
1279 		glw::GLenum internalformat				= internalformats[n_internalformat];
1280 		bool		is_color_renderable			= false;
1281 		bool		is_depth_stencil_renderable = false;
1282 
1283 		if (internalformat == GL_DEPTH24_STENCIL8)
1284 		{
1285 			is_depth_stencil_renderable = true;
1286 		}
1287 		else if (internalformat != GL_DEPTH_COMPONENT32F)
1288 		{
1289 			is_color_renderable = true;
1290 		}
1291 
1292 		/* Determine a value to be used for samples argument in subsequent
1293 		 * glTexStorage2DMultisample() call. */
1294 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
1295 							   &gl_max_internalformat_samples);
1296 
1297 		GLU_EXPECT_NO_ERROR(gl.getError(),
1298 							"Could not retrieve maximum supported amount of samples for internal format");
1299 
1300 		glw::GLint samples = gl_max_internalformat_samples;
1301 
1302 		/* Skip formats that are not multisampled in the implementation */
1303 		if (samples <= 1)
1304 		{
1305 			continue;
1306 		}
1307 
1308 		/* Set the texture object storage up */
1309 		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, 1, /* width */
1310 								   1,													  /* height */
1311 								   GL_FALSE);											  /* fixedsamplelocations */
1312 
1313 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call generated an unexpected error.");
1314 
1315 		/* Try to issue the invalid glFramebufferTexture2D() call */
1316 		glw::GLenum attachment = (is_color_renderable) ?
1317 									 GL_COLOR_ATTACHMENT0 :
1318 									 (is_depth_stencil_renderable) ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
1319 
1320 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, to_id, 0); /* level */
1321 
1322 		/* Make sure GL_INVALID_OPERATION error was generated */
1323 		glw::GLenum error_code = gl.getError();
1324 
1325 		if (error_code != GL_INVALID_OPERATION)
1326 		{
1327 			m_testCtx.getLog()
1328 				<< tcu::TestLog::Message << "An unexpected error code " << error_code
1329 				<< " instead of GL_INVALID_OPERATION was generated by an invalid glFramebufferTexture2D() call"
1330 				<< tcu::TestLog::EndMessage;
1331 
1332 			TCU_FAIL("Invalid error code reported by glFramebufferTexture2D() call.");
1333 		}
1334 
1335 		/* Re-create the texture object */
1336 		gl.deleteTextures(1, &to_id);
1337 		gl.genTextures(1, &to_id);
1338 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1339 
1340 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create the texture object.");
1341 	} /* for (all internalformats) */
1342 
1343 	/* All done */
1344 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1345 
1346 	return STOP;
1347 }
1348 
1349 /** Constructor.
1350  *
1351  *  @param context CTS context handle.
1352  **/
1353 MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test::
MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test(Context & context)1354 	MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test(Context& context)
1355 	: TestCase(context, "framebuffer_texture2d_used_with_invalid_level",
1356 			   "Checks GL_INVALID_VALUE is reported if glFramebufferTexture2D() "
1357 			   "is called with invalid level argument.")
1358 	, fbo_id(0)
1359 	, to_id(0)
1360 {
1361 	/* Left blank on purpose */
1362 }
1363 
1364 /** Deinitializes ES objects created during test execution */
deinit()1365 void MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test::deinit()
1366 {
1367 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1368 
1369 	if (fbo_id != 0)
1370 	{
1371 		gl.deleteFramebuffers(1, &fbo_id);
1372 
1373 		fbo_id = 0;
1374 	}
1375 
1376 	if (to_id != 0)
1377 	{
1378 		gl.deleteTextures(1, &to_id);
1379 
1380 		to_id = 0;
1381 	}
1382 
1383 	/* Call base class' deinit() */
1384 	TestCase::deinit();
1385 }
1386 
1387 /** Initializes ES objects created during test execution */
initInternals()1388 void MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test::initInternals()
1389 {
1390 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1391 
1392 	/* Generate and bind a framebuffer object */
1393 	gl.genFramebuffers(1, &fbo_id);
1394 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
1395 
1396 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
1397 
1398 	/* Generate and bind a texture object to GL_TEXTURE_2D_MULTISAMPLE texture target */
1399 	gl.genTextures(1, &to_id);
1400 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1401 
1402 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
1403 }
1404 
1405 /** Executes test iteration.
1406  *
1407  *  @return Returns STOP when test has finished executing.
1408  */
iterate()1409 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidFramebufferTexture2DCalls2Test::iterate()
1410 {
1411 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1412 
1413 	initInternals();
1414 
1415 	/* For storing format specific maximum number of samples */
1416 	glw::GLint gl_max_internalformat_samples = 0;
1417 
1418 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_INTEGER_SAMPLES and/or GL_MAX_SAMPLE values");
1419 
1420 	/* Iterate through all internalformats to be used for the test */
1421 	const glw::GLenum internalformats[] = {
1422 		GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I
1423 	};
1424 	const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
1425 
1426 	for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1427 	{
1428 		glw::GLenum internalformat		= internalformats[n_internalformat];
1429 		bool		is_color_renderable = false;
1430 		bool		is_depth_renderable = false;
1431 
1432 		if (internalformat == GL_DEPTH_COMPONENT32F)
1433 		{
1434 			is_depth_renderable = true;
1435 		}
1436 		else if (internalformat != GL_DEPTH24_STENCIL8)
1437 		{
1438 			is_color_renderable = true;
1439 		}
1440 
1441 		/* Determine a value to be used for samples argument in subsequent
1442 		 * glTexStorage2DMultisample() call. */
1443 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
1444 							   &gl_max_internalformat_samples);
1445 
1446 		GLU_EXPECT_NO_ERROR(gl.getError(),
1447 							"Could not retrieve maximum supported amount of samples for internal format");
1448 
1449 		glw::GLint samples = gl_max_internalformat_samples;
1450 
1451 		/* Skip formats that are not multisampled in implementation */
1452 		if (samples <= 1)
1453 		{
1454 			continue;
1455 		}
1456 
1457 		/* Set the texture object storage up */
1458 		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, 1, /* width */
1459 								   1,													  /* height */
1460 								   GL_FALSE);											  /* fixedsamplelocations */
1461 
1462 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call generated an unexpected error.");
1463 
1464 		/* Try to issue the invalid glFramebufferTexture2D() call */
1465 		glw::GLenum attachment = (is_color_renderable) ?
1466 									 GL_COLOR_ATTACHMENT0 :
1467 									 (is_depth_renderable) ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT;
1468 
1469 		/* From spec:
1470 		 *
1471 		 * If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero. If textarget
1472 		 * is one of the cube map face targets from table 3.21, then level must be greater
1473 		 * than or equal to zero and less than or equal to log2 of the value of MAX_CUBE_-
1474 		 * MAP_TEXTURE_SIZE. If textarget is TEXTURE_2D, level must be greater than or
1475 		 * equal to zero and no larger than log2 of the value of MAX_TEXTURE_SIZE.
1476 		 */
1477 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D_MULTISAMPLE, to_id, 1); /* level */
1478 
1479 		/* Make sure GL_INVALID_VALUE error was generated */
1480 		glw::GLenum error_code = gl.getError();
1481 
1482 		if (error_code != GL_INVALID_VALUE)
1483 		{
1484 			m_testCtx.getLog()
1485 				<< tcu::TestLog::Message << "An unexpected error code " << error_code
1486 				<< " instead of GL_INVALID_VALUE was generated by an invalid glFramebufferTexture2D() call"
1487 				<< tcu::TestLog::EndMessage;
1488 
1489 			TCU_FAIL("Invalid error code reported by glFramebufferTexture2D() call.");
1490 		}
1491 
1492 		/* Re-create the texture object */
1493 		gl.deleteTextures(1, &to_id);
1494 		gl.genTextures(1, &to_id);
1495 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1496 
1497 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create the texture object.");
1498 	} /* for (all internalformats) */
1499 
1500 	/* All done */
1501 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1502 
1503 	return STOP;
1504 }
1505 
1506 /** Constructor.
1507  *
1508  *  @param context CTS context handle.
1509  **/
1510 MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test::
MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test(Context & context)1511 	MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test(Context& context)
1512 	: TestCase(context, "framebuffer_texture_layer_used_for_invalid_texture_target",
1513 			   "Checks GL_INVALID_OPERATION is reported if 2D multisample texture is used for a "
1514 			   "glFramebufferTextureLayer() call")
1515 	, fbo_id(0)
1516 	, to_id(0)
1517 {
1518 	/* Left blank on purpose */
1519 }
1520 
1521 /** Deinitializes ES objects created during test execution */
deinit()1522 void MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test::deinit()
1523 {
1524 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1525 
1526 	if (fbo_id != 0)
1527 	{
1528 		gl.deleteFramebuffers(1, &fbo_id);
1529 
1530 		fbo_id = 0;
1531 	}
1532 
1533 	if (to_id != 0)
1534 	{
1535 		gl.deleteTextures(1, &to_id);
1536 
1537 		to_id = 0;
1538 	}
1539 
1540 	/* Call base class' deinit() */
1541 	TestCase::deinit();
1542 }
1543 
1544 /** Initializes ES objects created during test execution */
initInternals()1545 void MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test::initInternals()
1546 {
1547 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1548 
1549 	/* Generate and bind a framebuffer object */
1550 	gl.genFramebuffers(1, &fbo_id);
1551 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
1552 
1553 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
1554 
1555 	/* Generate and bind a texture object to GL_TEXTURE_2D_MULTISAMPLE texture target */
1556 	gl.genTextures(1, &to_id);
1557 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1558 
1559 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
1560 }
1561 
1562 /** Executes test iteration.
1563  *
1564  *  @return Returns STOP when test has finished executing.
1565  */
iterate()1566 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls1Test::iterate()
1567 {
1568 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1569 
1570 	initInternals();
1571 
1572 	/* For storing format specific maximum number of samples */
1573 	glw::GLint gl_max_internalformat_samples = 0;
1574 
1575 	/* Iterate through all internalformats to be used for the test */
1576 	const glw::GLenum internalformats[] = {
1577 		GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I
1578 	};
1579 	const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
1580 
1581 	for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1582 	{
1583 		glw::GLenum internalformat		= internalformats[n_internalformat];
1584 		bool		is_color_renderable = false;
1585 		bool		is_depth_renderable = false;
1586 
1587 		if (internalformat == GL_DEPTH_COMPONENT32F)
1588 		{
1589 			is_depth_renderable = true;
1590 		}
1591 		else if (internalformat != GL_DEPTH24_STENCIL8)
1592 		{
1593 			is_color_renderable = true;
1594 		}
1595 
1596 		/* Determine a value to be used for samples argument in subsequent
1597 		 * glTexStorage2DMultisample() call. */
1598 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
1599 							   &gl_max_internalformat_samples);
1600 
1601 		GLU_EXPECT_NO_ERROR(gl.getError(),
1602 							"Could not retrieve maximum supported amount of samples for internal format");
1603 
1604 		glw::GLint samples = gl_max_internalformat_samples;
1605 
1606 		/* Skip formats that are not multisampled in implementation */
1607 		if (samples <= 1)
1608 		{
1609 			continue;
1610 		}
1611 
1612 		/* Set the texture object storage up */
1613 		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, 2, /* width */
1614 								   2,													  /* height */
1615 								   GL_FALSE);											  /* fixedsamplelocations */
1616 
1617 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call generated an unexpected error.");
1618 
1619 		/* Try to issue the invalid glFramebufferTextureLayer() call */
1620 		glw::GLenum attachment = (is_color_renderable) ?
1621 									 GL_COLOR_ATTACHMENT0 :
1622 									 (is_depth_renderable) ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT;
1623 
1624 		gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachment, to_id, 0, /* level */
1625 								   0);										  /* layer */
1626 
1627 		/* Make sure GL_INVALID_OPERATION error was generated */
1628 		glw::GLenum error_code = gl.getError();
1629 
1630 		if (error_code != GL_INVALID_OPERATION)
1631 		{
1632 			m_testCtx.getLog()
1633 				<< tcu::TestLog::Message << "An unexpected error code " << error_code
1634 				<< " instead of GL_INVALID_OPERATION was generated by an invalid glFramebufferTextureLayer() call"
1635 				<< tcu::TestLog::EndMessage;
1636 
1637 			TCU_FAIL("Invalid error code reported by glFramebufferTextureLayer() call.");
1638 		}
1639 
1640 		/* Re-create the texture object */
1641 		gl.deleteTextures(1, &to_id);
1642 		gl.genTextures(1, &to_id);
1643 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1644 
1645 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create the texture object.");
1646 	} /* for (all internalformats) */
1647 
1648 	/* All done */
1649 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1650 
1651 	return STOP;
1652 }
1653 
1654 /** Constructor.
1655  *
1656  *  @param context CTS context handle.
1657  **/
1658 MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test::
MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test(Context & context)1659 	MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test(Context& context)
1660 	: TestCase(context, "framebuffer_texture_layer_used_with_invalid_level_argument",
1661 			   "Checks GL_INVALID_VALUE error is reported if a glFramebufferTextureLayer() call"
1662 			   " is made with level exceeding amount of layers defined for a 2D multisample"
1663 			   " array texture")
1664 	, fbo_id(0)
1665 	, to_id(0)
1666 {
1667 	/* Left blank on purpose */
1668 }
1669 
1670 /** Deinitializes ES objects created during test execution */
deinit()1671 void MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test::deinit()
1672 {
1673 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1674 
1675 	if (fbo_id != 0)
1676 	{
1677 		gl.deleteFramebuffers(1, &fbo_id);
1678 
1679 		fbo_id = 0;
1680 	}
1681 
1682 	if (to_id != 0)
1683 	{
1684 		gl.deleteTextures(1, &to_id);
1685 
1686 		to_id = 0;
1687 	}
1688 
1689 	/* Call base class' deinit() */
1690 	TestCase::deinit();
1691 }
1692 
1693 /** Initializes ES objects created during test execution */
initInternals()1694 void MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test::initInternals()
1695 {
1696 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1697 
1698 	/* Generate and bind a framebuffer object */
1699 	gl.genFramebuffers(1, &fbo_id);
1700 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo_id);
1701 
1702 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
1703 
1704 	/* Generate and bind a texture object to GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES texture target */
1705 	gl.genTextures(1, &to_id);
1706 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id);
1707 
1708 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
1709 }
1710 
1711 /** Executes test iteration.
1712  *
1713  *  @return Returns STOP when test has finished executing.
1714  */
iterate()1715 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidFramebufferTextureLayerCalls2Test::iterate()
1716 {
1717 	if (!m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array"))
1718 	{
1719 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "OES_texture_storage_multisample_2d_array");
1720 
1721 		return STOP;
1722 	}
1723 
1724 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1725 
1726 	initInternals();
1727 
1728 	/* For storing format specific maximum number of samples */
1729 	glw::GLint gl_max_internalformat_samples = 0;
1730 
1731 	/* Iterate through all internalformats to be used for the test */
1732 	const glw::GLenum internalformats[] = {
1733 		GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I
1734 	};
1735 	const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
1736 
1737 	for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1738 	{
1739 		glw::GLenum internalformat		= internalformats[n_internalformat];
1740 		bool		is_color_renderable = false;
1741 		bool		is_depth_renderable = false;
1742 
1743 		if (internalformat == GL_DEPTH_COMPONENT32F)
1744 		{
1745 			is_depth_renderable = true;
1746 		}
1747 		else if (internalformat != GL_DEPTH24_STENCIL8)
1748 		{
1749 			is_color_renderable = true;
1750 		}
1751 
1752 		/* Determine a value to be used for samples argument in subsequent
1753 		 * glTexStorage2DMultisample() call. */
1754 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
1755 							   &gl_max_internalformat_samples);
1756 
1757 		/* Get MAX_TEXTURE_SIZE and calculate max level */
1758 		glw::GLint gl_max_texture_size = 0;
1759 		gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max_texture_size);
1760 		const glw::GLint max_level = glw::GLint(log(double(gl_max_texture_size)) / log(2.0));
1761 
1762 		GLU_EXPECT_NO_ERROR(gl.getError(),
1763 							"Could not retrieve maximum supported amount of samples for internal format");
1764 
1765 		glw::GLint samples = gl_max_internalformat_samples;
1766 
1767 		/* Set the texture object storage up */
1768 		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samples, internalformat, 2, /* width */
1769 								   2,																/* height */
1770 								   2,																/* depth */
1771 								   GL_FALSE); /* fixedsamplelocations */
1772 
1773 		GLU_EXPECT_NO_ERROR(gl.getError(), "gltexStorage3DMultisample() call generated an unexpected error.");
1774 
1775 		/* Try to issue the invalid glFramebufferTextureLayer() call */
1776 		glw::GLenum attachment = (is_color_renderable) ?
1777 									 GL_COLOR_ATTACHMENT0 :
1778 									 (is_depth_renderable) ? GL_DEPTH_ATTACHMENT : GL_DEPTH_STENCIL_ATTACHMENT;
1779 
1780 		gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, attachment, to_id,
1781 								   max_level + 1, /* level - must be <= log_2(MAX_TEXTURE_SIZE) */
1782 								   0);			  /* layer */
1783 
1784 		/* Make sure GL_INVALID_VALUE error was generated */
1785 		glw::GLenum error_code = gl.getError();
1786 
1787 		if (error_code != GL_INVALID_VALUE)
1788 		{
1789 			m_testCtx.getLog()
1790 				<< tcu::TestLog::Message << "An unexpected error code " << error_code
1791 				<< " instead of GL_INVALID_VALUE was generated by an invalid glFramebufferTextureLayer() call"
1792 				<< tcu::TestLog::EndMessage;
1793 
1794 			TCU_FAIL("Invalid error code reported by glFramebufferTextureLayer() call.");
1795 		}
1796 
1797 		/* Re-create the texture object */
1798 		gl.deleteTextures(1, &to_id);
1799 		gl.genTextures(1, &to_id);
1800 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id);
1801 
1802 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create the texture object.");
1803 	} /* for (all internalformats) */
1804 
1805 	/* All done */
1806 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1807 
1808 	return STOP;
1809 }
1810 
1811 /** Constructor.
1812  *
1813  *  @param context CTS context handle.
1814  **/
1815 MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test::
MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test(Context & context)1816 	MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test(Context& context)
1817 	: TestCase(context, "renderbuffer_storage_multisample_invalid_samples_argument_for_noninteger_internalformats",
1818 			   "GL_INVALID_OPERATION error is reported for glRenderbufferStorageMultisample() "
1819 			   "calls, for which samples argument > MAX_SAMPLES for non-integer internalformats")
1820 	, rbo_id(0)
1821 {
1822 	/* Left blank on purpose */
1823 }
1824 
1825 /** Deinitializes ES objects created during test execution */
deinit()1826 void MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test::deinit()
1827 {
1828 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1829 
1830 	if (rbo_id != 0)
1831 	{
1832 		gl.deleteRenderbuffers(1, &rbo_id);
1833 
1834 		rbo_id = 0;
1835 	}
1836 
1837 	/* Call base class' deinit() */
1838 	TestCase::deinit();
1839 }
1840 
1841 /** Initializes ES objects created during test execution */
initInternals()1842 void MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test::initInternals()
1843 {
1844 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1845 
1846 	gl.genRenderbuffers(1, &rbo_id);
1847 	gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
1848 
1849 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
1850 }
1851 
1852 /** Executes test iteration.
1853  *
1854  *  @return Returns STOP when test has finished executing.
1855  */
iterate()1856 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls1Test::iterate()
1857 {
1858 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1859 
1860 	initInternals();
1861 
1862 	/* Retrieve GL_MAX_SAMPLES pname value */
1863 	glw::GLint gl_max_samples_value = 0;
1864 
1865 	gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
1866 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_SAMPLES value.");
1867 
1868 	/* Iterate through a set of valid non-integer internalformats */
1869 	const glw::GLenum noninteger_internalformats[] = {
1870 		GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_STENCIL_INDEX8
1871 	};
1872 	const unsigned int n_noninteger_internalformats =
1873 		sizeof(noninteger_internalformats) / sizeof(noninteger_internalformats[0]);
1874 
1875 	for (unsigned int n_internalformat = 0; n_internalformat < n_noninteger_internalformats; ++n_internalformat)
1876 	{
1877 		glw::GLenum		  error_code						  = GL_NO_ERROR;
1878 		const glw::GLenum internalformat					  = noninteger_internalformats[n_internalformat];
1879 		glw::GLint		  gl_max_internalformat_samples_value = -1;
1880 
1881 		/* Retrieve maximum amount of samples available for the texture target considered */
1882 		gl.getInternalformativ(GL_RENDERBUFFER, internalformat, GL_SAMPLES, 1, &gl_max_internalformat_samples_value);
1883 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed to retrieve GL_SAMPLES");
1884 
1885 		/* Execute the test */
1886 		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, gl_max_internalformat_samples_value + 1, internalformat,
1887 										  1,  /* width */
1888 										  1); /* height */
1889 
1890 		error_code = gl.getError();
1891 		if (error_code != GL_INVALID_OPERATION)
1892 		{
1893 			m_testCtx.getLog() << tcu::TestLog::Message << "glRenderbufferStorageMultisample() generated error code "
1894 							   << error_code << " when GL_INVALID_OPERATION was expected." << tcu::TestLog::EndMessage;
1895 
1896 			TCU_FAIL("Invalid error code generated by glRenderbufferStorageMultisample() call.");
1897 		}
1898 	} /* for (all internalformats) */
1899 
1900 	/* All done */
1901 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1902 
1903 	return STOP;
1904 }
1905 
1906 /** Constructor.
1907  *
1908  *  @param context CTS context handle.
1909  **/
1910 MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test::
MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test(Context & context)1911 	MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test(Context& context)
1912 	: TestCase(context, "renderbuffer_storage_multisample_invalid_samples_argument_for_integer_internalformats",
1913 			   "GL_INVALID_OPERATION error is reported for glRenderbufferStorageMultisample() calls, "
1914 			   "for which samples argument > MAX_INTEGER_SAMPLES for integer internalformats")
1915 	, rbo_id(0)
1916 {
1917 	/* Left blank on purpose */
1918 }
1919 
1920 /** Deinitializes ES objects created during test execution */
deinit()1921 void MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test::deinit()
1922 {
1923 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1924 
1925 	if (rbo_id != 0)
1926 	{
1927 		gl.deleteRenderbuffers(1, &rbo_id);
1928 
1929 		rbo_id = 0;
1930 	}
1931 
1932 	/* Call base class' deinit() */
1933 	TestCase::deinit();
1934 }
1935 
1936 /** Initializes ES objects created during test execution */
initInternals()1937 void MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test::initInternals()
1938 {
1939 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1940 
1941 	gl.genRenderbuffers(1, &rbo_id);
1942 	gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
1943 
1944 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
1945 }
1946 
1947 /** Executes test iteration.
1948  *
1949  *  @return Returns STOP when test has finished executing.
1950  */
iterate()1951 tcu::TestNode::IterateResult MultisampleTextureDependenciesInvalidRenderbufferStorageMultisampleCalls2Test::iterate()
1952 {
1953 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1954 
1955 	initInternals();
1956 
1957 	/* Retrieve GL_MAX_INTEGER_SAMPLES pname value */
1958 	glw::GLint gl_max_integer_samples_value = 0;
1959 
1960 	gl.getIntegerv(GL_MAX_INTEGER_SAMPLES, &gl_max_integer_samples_value);
1961 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_INTEGER_SAMPLES value.");
1962 
1963 	/* Iterate through a set of valid integer internalformats */
1964 	const glw::GLenum  integer_internalformats[] = { GL_RG8UI, GL_RGBA32I };
1965 	const unsigned int n_integer_internalformats = sizeof(integer_internalformats) / sizeof(integer_internalformats[0]);
1966 
1967 	for (unsigned int n_internalformat = 0; n_internalformat < n_integer_internalformats; ++n_internalformat)
1968 	{
1969 		glw::GLenum		  error_code	 = GL_NO_ERROR;
1970 		const glw::GLenum internalformat = integer_internalformats[n_internalformat];
1971 
1972 		/* Execute the test */
1973 		gl.renderbufferStorageMultisample(GL_RENDERBUFFER, gl_max_integer_samples_value + 1, internalformat,
1974 										  1,  /* width */
1975 										  1); /* height */
1976 
1977 		error_code = gl.getError();
1978 		if (error_code != GL_INVALID_OPERATION)
1979 		{
1980 			m_testCtx.getLog() << tcu::TestLog::Message << "glRenderbufferStorageMultisample() generated error code "
1981 							   << error_code << " when GL_INVALID_OPERATION was expected." << tcu::TestLog::EndMessage;
1982 
1983 			TCU_FAIL("Invalid error code generated by glRenderbufferStorageMultisample() call.");
1984 		}
1985 	} /* for (all internalformats) */
1986 
1987 	/* All done */
1988 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1989 
1990 	return STOP;
1991 }
1992 
1993 /** Constructor.
1994  *
1995  *  @param context CTS context handle.
1996  **/
1997 MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest::
MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest(Context & context)1998 	MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest(Context& context)
1999 	: TestCase(context, "no_error_generated_for_valid_framebuffer_texture2d_calls",
2000 			   "No error is reported for glFramebufferTexture2D() calls using "
2001 			   "GL_TEXTURE_2D_MULTISAMPLE texture target.")
2002 	, fbo_id(0)
2003 	, to_id(0)
2004 {
2005 	/* Left blank on purpose */
2006 }
2007 
2008 /** Deinitializes ES objects created during test execution */
deinit()2009 void MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest::deinit()
2010 {
2011 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2012 
2013 	if (fbo_id != 0)
2014 	{
2015 		gl.deleteFramebuffers(1, &fbo_id);
2016 
2017 		fbo_id = 0;
2018 	}
2019 
2020 	if (to_id != 0)
2021 	{
2022 		gl.deleteTextures(1, &to_id);
2023 
2024 		to_id = 0;
2025 	}
2026 
2027 	/* Call base class' deinit() */
2028 	TestCase::deinit();
2029 }
2030 
2031 /** Initializes ES objects created during test execution */
initInternals()2032 void MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest::initInternals()
2033 {
2034 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2035 
2036 	/* Set up a framebuffer object */
2037 	gl.genFramebuffers(1, &fbo_id);
2038 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
2039 
2040 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a framebuffer object");
2041 }
2042 
2043 /** Executes test iteration.
2044  *
2045  *  @return Returns STOP when test has finished executing.
2046  */
2047 tcu::TestNode::IterateResult MultisampleTextureDependenciesNoErrorGeneratedForValidFramebufferTexture2DCallsTest::
iterate()2048 	iterate()
2049 {
2050 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2051 
2052 	initInternals();
2053 
2054 	/* For storing format specific maximum number of samples */
2055 	glw::GLint gl_max_internalformat_samples = 0;
2056 
2057 	/* Iterate through all internalformats */
2058 	const glw::GLenum internalformats[] = {
2059 		GL_RGB8, GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8, GL_RGBA32I
2060 	};
2061 	const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
2062 
2063 	for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
2064 	{
2065 		glw::GLenum internalformat = internalformats[n_internalformat];
2066 
2067 		/* Determine a value to be used for samples argument in subsequent
2068 		 * glTexStorage2DMultisample() call. */
2069 		gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, internalformat, GL_SAMPLES, 1,
2070 							   &gl_max_internalformat_samples);
2071 
2072 		GLU_EXPECT_NO_ERROR(gl.getError(),
2073 							"Could not retrieve maximum supported amount of samples for internal format");
2074 
2075 		glw::GLint samples = gl_max_internalformat_samples;
2076 
2077 		/* Skip formats that are not multisampled in implementation */
2078 		if (samples <= 1)
2079 		{
2080 			continue;
2081 		}
2082 
2083 		/* Set up a texture object. */
2084 		gl.genTextures(1, &to_id);
2085 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
2086 
2087 		gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, 1, /* width */
2088 								   1,													  /* height */
2089 								   GL_FALSE);											  /* fixedsamplelocations */
2090 
2091 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a texture object");
2092 
2093 		/* Determine attachment type for internalformat considered */
2094 		glw::GLenum attachment_type = GL_COLOR_ATTACHMENT0;
2095 
2096 		if (internalformat == GL_DEPTH_COMPONENT32F)
2097 		{
2098 			attachment_type = GL_DEPTH_ATTACHMENT;
2099 		}
2100 		else if (internalformat == GL_DEPTH24_STENCIL8)
2101 		{
2102 			attachment_type = GL_DEPTH_STENCIL_ATTACHMENT;
2103 		}
2104 
2105 		/* Attach it to the FBO */
2106 		gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment_type, GL_TEXTURE_2D_MULTISAMPLE, to_id, 0); /* level */
2107 
2108 		GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
2109 
2110 		/* Release the texture object */
2111 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
2112 		gl.deleteTextures(1, &to_id);
2113 
2114 		to_id = 0;
2115 
2116 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not release the texture object");
2117 	} /* for (all internalformats) */
2118 
2119 	/* All done */
2120 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2121 
2122 	return STOP;
2123 }
2124 
2125 /** Constructor.
2126  *
2127  *  @param context CTS context handle.
2128  **/
2129 MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest::
MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest(Context & context)2130 	MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest(Context& context)
2131 	: TestCase(context, "no_error_generated_for_valid_renderbuffer_storage_multisample_calls",
2132 			   "No error is reported for valid glRenderbufferStorageMultisample() calls.")
2133 	, rbo_id(0)
2134 {
2135 	/* Left blank on purpose */
2136 }
2137 
2138 /** Deinitializes ES objects created during test execution */
deinit()2139 void MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest::deinit()
2140 {
2141 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2142 
2143 	if (rbo_id != 0)
2144 	{
2145 		gl.deleteRenderbuffers(1, &rbo_id);
2146 
2147 		rbo_id = 0;
2148 	}
2149 
2150 	/* Call base class' deinit() */
2151 	TestCase::deinit();
2152 }
2153 
2154 /** Initializes ES objects created during test execution */
initInternals()2155 void MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest::initInternals()
2156 {
2157 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2158 
2159 	gl.genRenderbuffers(1, &rbo_id);
2160 	gl.bindRenderbuffer(GL_RENDERBUFFER, rbo_id);
2161 
2162 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up a renderbuffer object");
2163 }
2164 
2165 /** Executes test iteration.
2166  *
2167  *  @return Returns STOP when test has finished executing.
2168  */
2169 tcu::TestNode::IterateResult MultisampleTextureDependenciesNoErrorGeneratedForValidRenderbufferStorageMultisampleCallsTest::
iterate()2170 	iterate()
2171 {
2172 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2173 
2174 	initInternals();
2175 
2176 	/* For storing format specific maximum number of samples */
2177 	glw::GLint gl_max_internalformat_samples = 0;
2178 
2179 	/* Iterate through a set of valid non-integer and integer
2180 	 internalformats and a set of all legal samples argument values */
2181 	const glw::GLenum internalformats[] = {
2182 		GL_RGB8,		   GL_RGB565, GL_SRGB8_ALPHA8, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8,
2183 		GL_STENCIL_INDEX8, GL_RG8UI,  GL_RGBA32I
2184 	};
2185 	const unsigned int n_internalformats = sizeof(internalformats) / sizeof(internalformats[0]);
2186 
2187 	for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
2188 	{
2189 		glw::GLenum internalformat = internalformats[n_internalformat];
2190 
2191 		/* Determine a value to be used for samples argument in subsequent
2192 		 * glTexStorage2DMultisample() call. */
2193 		gl.getInternalformativ(GL_RENDERBUFFER, internalformat, GL_SAMPLES, 1, &gl_max_internalformat_samples);
2194 
2195 		GLU_EXPECT_NO_ERROR(gl.getError(),
2196 							"Could not retrieve maximum supported amount of samples for internal format");
2197 
2198 		for (int samples = 1; samples <= gl_max_internalformat_samples; ++samples)
2199 		{
2200 			/* Execute the test */
2201 			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat, 1, 1);
2202 
2203 			GLU_EXPECT_NO_ERROR(gl.getError(),
2204 								"A valid glRenderbufferStorageMultisample() call has reported an error.");
2205 		} /* for (all legal samples argument values) */
2206 	}	 /* for (all internalformats) */
2207 
2208 	/* All done */
2209 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2210 
2211 	return STOP;
2212 }
2213 
2214 /** Constructor.
2215  *
2216  *  @param context CTS context handle.
2217  **/
MultisampleTextureDependenciesTexParameterTest(Context & context)2218 MultisampleTextureDependenciesTexParameterTest::MultisampleTextureDependenciesTexParameterTest(Context& context)
2219 	: TestCase(context, "tex_parameter_support",
2220 			   "Verifies glTexParameter*() behavior when used against multisample texture targets")
2221 	, to_id_multisample_2d(0)
2222 	, to_id_multisample_2d_array(0)
2223 {
2224 	/* Left blank on purpose */
2225 }
2226 
2227 /* Calls glTexParameterf(), glTexParameterfv(), glTexParameteri() and
2228  * glTexParameteriv(). For each invocation, the function checks if
2229  * the error code reported after each call matches the expected value.
2230  * If the values differ, an info message is logged and TestError exception
2231  * is thrown.
2232  *
2233  * @param expected_error_code Expected GL error code.
2234  * @param value               Integer value to use. For glTexParameterf()
2235  *                            or glTexParameterfv(), the value will be cast
2236  *                            onto a float type prior to calling.
2237  * @param pname               GL pname to use for glTexParameter*() calls.
2238  * @param texture_target      Texture target to use for glTexParameter*() calls.
2239  */
checkAllTexParameterInvocations(glw::GLenum expected_error_code,glw::GLint value,glw::GLenum pname,glw::GLenum texture_target)2240 void MultisampleTextureDependenciesTexParameterTest::checkAllTexParameterInvocations(glw::GLenum expected_error_code,
2241 																					 glw::GLint  value,
2242 																					 glw::GLenum pname,
2243 																					 glw::GLenum texture_target)
2244 {
2245 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2246 
2247 	glw::GLenum		   error_code  = GL_NO_ERROR;
2248 	const glw::GLfloat float_value = (glw::GLfloat)value;
2249 	const glw::GLint   int_value   = value;
2250 
2251 	/* glTexParameterf() */
2252 	gl.texParameterf(texture_target, pname, float_value);
2253 
2254 	error_code = gl.getError();
2255 
2256 	if (error_code != expected_error_code)
2257 	{
2258 		m_testCtx.getLog() << tcu::TestLog::Message << "glTexParameterf() call generated an error " << error_code
2259 						   << " instead of the expected error code " << expected_error_code << tcu::TestLog::EndMessage;
2260 
2261 		TCU_FAIL("glTexParameterf() call generated an unexpected error.");
2262 	}
2263 
2264 	/* glTexParameteri() */
2265 	gl.texParameteri(texture_target, pname, int_value);
2266 
2267 	error_code = gl.getError();
2268 
2269 	if (error_code != expected_error_code)
2270 	{
2271 		m_testCtx.getLog() << tcu::TestLog::Message << "glTexParameteri() call generated an error " << error_code
2272 						   << " instead of the expected error code " << expected_error_code << tcu::TestLog::EndMessage;
2273 
2274 		TCU_FAIL("glTexParameterf() call generated an unexpected error.");
2275 	}
2276 
2277 	/* glTexParameterfv() */
2278 	gl.texParameterfv(texture_target, pname, &float_value);
2279 
2280 	error_code = gl.getError();
2281 
2282 	if (error_code != expected_error_code)
2283 	{
2284 		m_testCtx.getLog() << tcu::TestLog::Message << "glTexParameterfv() call generated an error " << error_code
2285 						   << " instead of the expected error code " << expected_error_code << tcu::TestLog::EndMessage;
2286 
2287 		TCU_FAIL("glTexParameterfv() call generated an unexpected error.");
2288 	}
2289 
2290 	/* glTexParameteriv() */
2291 	gl.texParameteriv(texture_target, pname, &int_value);
2292 
2293 	error_code = gl.getError();
2294 
2295 	if (error_code != expected_error_code)
2296 	{
2297 		m_testCtx.getLog() << tcu::TestLog::Message << "glTexParameteriv() call generated an error " << error_code
2298 						   << " instead of the expected error code " << expected_error_code << tcu::TestLog::EndMessage;
2299 
2300 		TCU_FAIL("glTexParameteriv() call generated an unexpected error.");
2301 	}
2302 }
2303 
2304 /** Deinitializes ES objects created during test execution */
deinit()2305 void MultisampleTextureDependenciesTexParameterTest::deinit()
2306 {
2307 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2308 
2309 	if (to_id_multisample_2d != 0)
2310 	{
2311 		gl.deleteTextures(1, &to_id_multisample_2d);
2312 
2313 		to_id_multisample_2d = 0;
2314 	}
2315 
2316 	if (to_id_multisample_2d_array != 0)
2317 	{
2318 		gl.deleteTextures(1, &to_id_multisample_2d_array);
2319 
2320 		to_id_multisample_2d_array = 0;
2321 	}
2322 
2323 	/* Call base class' deinit() */
2324 	TestCase::deinit();
2325 }
2326 
2327 /** Executes test iteration.
2328  *
2329  *  @return Returns STOP when test has finished executing.
2330  */
iterate()2331 tcu::TestNode::IterateResult MultisampleTextureDependenciesTexParameterTest::iterate()
2332 {
2333 	bool are_multisample_2d_array_tos_supported =
2334 		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
2335 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2336 
2337 	/* Set up texture objects */
2338 	gl.genTextures(1, &to_id_multisample_2d);
2339 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_multisample_2d);
2340 
2341 	if (are_multisample_2d_array_tos_supported)
2342 	{
2343 		gl.genTextures(1, &to_id_multisample_2d_array);
2344 		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_multisample_2d_array);
2345 	}
2346 
2347 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up texture objects");
2348 
2349 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, /* samples */
2350 							   GL_RGBA8, 1,					 /* width */
2351 							   1,							 /* height */
2352 							   GL_FALSE);					 /* fixedsamplelocations */
2353 
2354 	GLU_EXPECT_NO_ERROR(gl.getError(),
2355 						"glTexStorage2DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE texture target");
2356 
2357 	if (are_multisample_2d_array_tos_supported)
2358 	{
2359 		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 1, /* samples */
2360 								   GL_RGBA8, 1,							   /* width */
2361 								   1,									   /* height */
2362 								   1,									   /* depth */
2363 								   GL_FALSE);							   /* fixedsamplelocations */
2364 
2365 		GLU_EXPECT_NO_ERROR(
2366 			gl.getError(),
2367 			"gltexStorage3DMultisample() call failed for GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES texture target");
2368 	}
2369 
2370 	/* Run the test for both multisample texture targets */
2371 	const glw::GLenum  texture_targets[] = { GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES };
2372 	const unsigned int n_texture_targets = sizeof(texture_targets) / sizeof(texture_targets[0]);
2373 
2374 	for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
2375 	{
2376 		glw::GLenum texture_target = texture_targets[n_texture_target];
2377 
2378 		if (!are_multisample_2d_array_tos_supported && texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES)
2379 		{
2380 			/* Skip the iteration */
2381 			continue;
2382 		}
2383 
2384 		/* Verify that setting GL_TEXTURE_BASE_LEVEL to 0 does not generate any 0. Using any other
2385 		 * value should generate GL_INVALID_OPERATION
2386 		 */
2387 		for (int n_iteration = 0; n_iteration < 2 /* iterations */; ++n_iteration)
2388 		{
2389 			glw::GLenum expected_error_code = (n_iteration == 0) ? GL_NO_ERROR : GL_INVALID_OPERATION;
2390 			glw::GLint  int_value			= (n_iteration == 0) ? 0 : 1;
2391 
2392 			checkAllTexParameterInvocations(expected_error_code, int_value, GL_TEXTURE_BASE_LEVEL, texture_target);
2393 		} /* for (all iterations) */
2394 	}	 /* for (both texture targets) */
2395 
2396 	/* Make sure that modifying sampler state information results in an error
2397 	 * for multisample texture targets. */
2398 	const glw::GLenum sampler_pnames[] = { GL_TEXTURE_MIN_FILTER, GL_TEXTURE_MAG_FILTER,   GL_TEXTURE_WRAP_S,
2399 										   GL_TEXTURE_WRAP_T,	 GL_TEXTURE_WRAP_R,	   GL_TEXTURE_MIN_LOD,
2400 										   GL_TEXTURE_MAX_LOD,	GL_TEXTURE_COMPARE_MODE, GL_TEXTURE_COMPARE_FUNC };
2401 	const unsigned int n_sampler_pnames = sizeof(sampler_pnames) / sizeof(sampler_pnames[0]);
2402 
2403 	for (unsigned int n_sampler_pname = 0; n_sampler_pname < n_sampler_pnames; ++n_sampler_pname)
2404 	{
2405 		glw::GLenum pname = sampler_pnames[n_sampler_pname];
2406 
2407 		for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
2408 		{
2409 			glw::GLenum texture_target = texture_targets[n_texture_target];
2410 
2411 			if (!are_multisample_2d_array_tos_supported && texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES)
2412 			{
2413 				/* Skip the iteration */
2414 				continue;
2415 			}
2416 
2417 			/* When <target> is TEXTURE_2D_MULTISAMPLE or
2418 			 TEXTURE_2D_MULTISAMPLE_ARRAY, certain texture parameters may not be
2419 			 specified. In this case, an INVALID_ENUM */
2420 			checkAllTexParameterInvocations(GL_INVALID_ENUM, 0, pname, texture_target);
2421 
2422 		} /* for (all texture targets) */
2423 	}	 /* for (all sampler properties) */
2424 
2425 	/* Make sure that modifying remaining texture parameters does not result in an error for
2426 	 * multisample texture targets. */
2427 	for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
2428 	{
2429 		glw::GLenum texture_target = texture_targets[n_texture_target];
2430 
2431 		if (!are_multisample_2d_array_tos_supported && texture_target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES)
2432 		{
2433 			/* Skip the iteration */
2434 			continue;
2435 		}
2436 
2437 		checkAllTexParameterInvocations(GL_NO_ERROR, 10, GL_TEXTURE_MAX_LEVEL, texture_target);
2438 		checkAllTexParameterInvocations(GL_NO_ERROR, GL_GREEN, GL_TEXTURE_SWIZZLE_R, texture_target);
2439 		checkAllTexParameterInvocations(GL_NO_ERROR, GL_BLUE, GL_TEXTURE_SWIZZLE_G, texture_target);
2440 		checkAllTexParameterInvocations(GL_NO_ERROR, GL_ALPHA, GL_TEXTURE_SWIZZLE_B, texture_target);
2441 		checkAllTexParameterInvocations(GL_NO_ERROR, GL_RED, GL_TEXTURE_SWIZZLE_A, texture_target);
2442 	}
2443 
2444 	/* All done */
2445 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2446 
2447 	return STOP;
2448 }
2449 } /* glcts namespace */
2450