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  es31cTextureStorageMultisampleTexStorage2DMultisampleTests.cpp
27 * \brief Implements conformance tests for glTexStorage2DMultisample()
28 *        entry-points (ES3.1 only)
29 */ /*-------------------------------------------------------------------*/
30
31#include "es31cTextureStorageMultisampleTexStorage2DMultisampleTests.hpp"
32#include "gluContextInfo.hpp"
33#include "gluDefs.hpp"
34#include "glwEnums.hpp"
35#include "glwFunctions.hpp"
36#include "tcuRenderTarget.hpp"
37#include "tcuTestLog.hpp"
38
39#include <algorithm>
40#include <string>
41#include <vector>
42
43namespace glcts
44{
45
46/** Constructor.
47 *
48 *  @param context Rendering context handle.
49 **/
50MultisampleTextureTexStorage2DGeneralSamplesNumberTest::MultisampleTextureTexStorage2DGeneralSamplesNumberTest(
51	Context& context)
52	: TestCase(context, "multisample_texture_tex_storage_2d_general_samples_number",
53			   "Verifies TexStorage2DMultisample() requests with exact number of samples"
54			   " reported by glGetInternalformativ() succeed and larger values rejected")
55	, to_id(0)
56{
57	/* Left blank on purpose */
58}
59
60/** Deinitializes ES objects created during test execution */
61void MultisampleTextureTexStorage2DGeneralSamplesNumberTest::deinit()
62{
63	/* Delete texture in case the test case failed */
64	deinitInternalIteration();
65
66	/* Call base class deinitialization routine */
67	glcts::TestCase::deinit();
68}
69
70/** Deinitializes GL ES objects specific to internal iteration */
71void MultisampleTextureTexStorage2DGeneralSamplesNumberTest::deinitInternalIteration()
72{
73	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
74
75	if (to_id != 0)
76	{
77		/* Delete texture object */
78		gl.deleteTextures(1, &to_id);
79
80		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete texture object");
81
82		to_id = 0;
83	}
84
85	/* Unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE texture target */
86	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
87
88	GLU_EXPECT_NO_ERROR(gl.getError(),
89						"Failed to unbind a texture object from GL_TEXTURE_2D_MULTISAMPLE texture target");
90}
91
92/** Initializes GL ES objects specific to internal iteration */
93void MultisampleTextureTexStorage2DGeneralSamplesNumberTest::initInternalIteration()
94{
95	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
96
97	/* Generate texture object id */
98	gl.genTextures(1, &to_id);
99
100	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed to generate texture");
101
102	/* Verify texture object has been generated properly */
103	if (to_id == 0)
104	{
105		TCU_FAIL("Texture object has not been generated properly");
106	}
107
108	/* Bind generated texture object ID to GL_TEXTURE_2D_MULTISAMPLE texture target */
109	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
110
111	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() reported an error");
112}
113
114/** Executes test iteration.
115 *
116 *  @return Always STOP.
117 */
118tcu::TestNode::IterateResult MultisampleTextureTexStorage2DGeneralSamplesNumberTest::iterate()
119{
120	/* Test case variables */
121	const glw::GLboolean  fixedsamplelocations  = GL_FALSE;
122	const glw::Functions& gl					= m_context.getRenderContext().getFunctions();
123	const glw::GLenum	 internalformat_list[] = { GL_R8,
124												GL_RGB565,
125												GL_RGB10_A2UI,
126												GL_SRGB8_ALPHA8,
127												GL_R8I,
128												GL_DEPTH_COMPONENT16,
129												GL_DEPTH_COMPONENT32F,
130												GL_DEPTH24_STENCIL8,
131												GL_DEPTH24_STENCIL8,
132												GL_DEPTH32F_STENCIL8 };
133	const int		   internalformat_list_count  = sizeof(internalformat_list) / sizeof(internalformat_list[0]);
134	glw::GLint		   internalformat_max_samples = -1; /* Will be determined later */
135	const glw::GLsizei height					  = 1;
136	const glw::GLsizei width					  = 1;
137	const glw::GLenum  target = GL_TEXTURE_2D_MULTISAMPLE; /* Test case uses GL_TEXTURE_2D_MULTISAMPLE target */
138	glw::GLint		   gl_max_samples_value = -1;
139
140	/* Get GL_MAX_SAMPLES value */
141	gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
142	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_MAX_SAMPLES value");
143
144	/* Iterate through all internal formats test case should check */
145	for (int internalformat_index = 0; internalformat_index < internalformat_list_count; internalformat_index++)
146	{
147		/* Iteration-specific internalformat */
148		glw::GLenum internalformat = internalformat_list[internalformat_index];
149
150		/* Subiteration. Case samples = internalformat_max_samples */
151		{
152			/* Initialize texture object and bind it to GL_TEXTURE_2D_MULTISAMPLE target */
153			initInternalIteration();
154
155			/* Retrieve maximum amount of samples available for the target's texture internalformat */
156			gl.getInternalformativ(target, internalformat, GL_SAMPLES, 1, &internalformat_max_samples);
157
158			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed to retrieve GL_SAMPLES value");
159
160			/* Issue call with valid parameters */
161			gl.texStorage2DMultisample(target, internalformat_max_samples, internalformat, width, height,
162									   fixedsamplelocations);
163
164			GLU_EXPECT_NO_ERROR(
165				gl.getError(),
166				"glTexStorage2DMultisample() call, for which a valid number of samples was used, has failed.");
167
168			/* Deinitialize texture object and unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE target */
169			deinitInternalIteration();
170		}
171
172		/* Subiteration. Case: samples > internalformat_max_samples */
173		{
174			/* Initialize texture object and bind it to GL_TEXTURE_2D_MULTISAMPLE target */
175			initInternalIteration();
176
177			/* Issue call with valid parameters, but invalid sample parameter */
178			gl.texStorage2DMultisample(target, internalformat_max_samples + 1, internalformat, width, height,
179									   fixedsamplelocations);
180
181			/* Check if the expected error code was reported */
182			/* From spec:
183			 * An INVALID_OPERATION error is generated if samples is greater than the
184			 * maximum number of samples supported for this target and internalformat.*/
185
186			/* Expect GL_INVALID_OPERATION error code. */
187			TCU_CHECK_MSG(gl.getError() == GL_INVALID_OPERATION,
188						  "glTexStorage2DMultisample() did not generate GL_INVALID_OPERATION error.");
189
190			/* Deinitialize texture object and unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE target */
191			deinitInternalIteration();
192		}
193	}
194
195	/* Test case passed */
196	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
197
198	return STOP;
199}
200
201/** Constructor.
202 *
203 *  @param context Rendering context handle.
204 **/
205MultisampleTextureTexStorage2DInvalidAndBorderCaseTextureSizesTest::
206	MultisampleTextureTexStorage2DInvalidAndBorderCaseTextureSizesTest(Context& context)
207	: TestCase(context, "multisample_texture_tex_storage_2d_invalid_and_border_case_texture_sizes",
208			   "Invalid multisample texture sizes are rejected; border cases are correctly accepted.")
209	, to_id(0)
210{
211	/* Left blank on purpose */
212}
213
214/** Deinitializes GL ES objects used by the test */
215void MultisampleTextureTexStorage2DInvalidAndBorderCaseTextureSizesTest::deinit()
216{
217	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
218
219	/* Call base class deinitialization routine */
220	glcts::TestCase::deinit();
221
222	/* Release test texture object */
223	if (to_id != 0)
224	{
225		gl.deleteTextures(1, &to_id);
226
227		to_id = 0;
228	}
229}
230
231/** Initializes GL ES objects used by the test */
232void MultisampleTextureTexStorage2DInvalidAndBorderCaseTextureSizesTest::initInternals()
233{
234	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
235
236	/* Generate texture object id */
237	gl.genTextures(1, &to_id);
238
239	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
240}
241
242/** Executes test iteration.
243 *
244 *  @return Always STOP.
245 */
246tcu::TestNode::IterateResult MultisampleTextureTexStorage2DInvalidAndBorderCaseTextureSizesTest::iterate()
247{
248	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
249
250	initInternals();
251
252	/* Retrieve GL_MAX_TEXTURE_SIZE pname value */
253	glw::GLint gl_max_texture_size_value = 0;
254
255	gl.getIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max_texture_size_value);
256	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_TEXTURE_SIZE pname value");
257
258	/* Try to set up a valid 2D multisample texture object of (max texture size, 1) resolution. */
259	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
260
261	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2 /* samples */, GL_RGBA8, gl_max_texture_size_value,
262							   1 /* height */, GL_TRUE /* fixedsamplelocations */);
263
264	GLU_EXPECT_NO_ERROR(gl.getError(),
265						"Valid glTexStorage2DMultisample() call ((max texture size, 1) resolution) failed");
266
267	/* Delete the texture object before we continue */
268	gl.deleteTextures(1, &to_id);
269
270	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
271
272	/* Create a new texture object and bind it to 2D multisample texture target. */
273	gl.genTextures(1, &to_id);
274	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
275
276	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create 2D multisample texture object");
277
278	/* Try to set up another valid 2D multisample texture object of (1, max texture size) resolution. */
279	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2 /* samples */, GL_RGBA8, 1 /* width */,
280							   gl_max_texture_size_value, GL_TRUE /* fixedsamplelocations */);
281
282	GLU_EXPECT_NO_ERROR(gl.getError(),
283						"Valid glTexStorage2DMultisample() call ((1, max texture size) resolution) failed");
284
285	/* Delete the texture object before we continue */
286	gl.deleteTextures(1, &to_id);
287
288	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
289
290	/* Create a new texture object and bind it to 2D multisample texture target. */
291	gl.genTextures(1, &to_id);
292	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
293
294	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create 2D multisample texture object");
295
296	/* Try to set up invalid 2D multisample texture objects. */
297	glw::GLenum error_code = GL_NO_ERROR;
298
299	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,			/* samples */
300							   GL_RGBA8, gl_max_texture_size_value + 1, /* width */
301							   1,										/* height */
302							   GL_TRUE);								/* fixedsamplelocations */
303
304	error_code = gl.getError();
305	if (error_code != GL_INVALID_VALUE)
306	{
307		TCU_FAIL("Invalid glTexStorage2DMultisample() call ((max texture size+1, 1) resolution) did not generate "
308				 "GL_INVALID_VALUE error");
309	}
310
311	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,  /* samples */
312							   GL_RGBA8, 1,					  /* width */
313							   gl_max_texture_size_value + 1, /* height */
314							   GL_TRUE);					  /* fixedsamplelocations */
315
316	error_code = gl.getError();
317	if (error_code != GL_INVALID_VALUE)
318	{
319		TCU_FAIL("Invalid glTexStorage2DMultisample() call ((1, max texture size+1) resolution) did not generate "
320				 "GL_INVALID_VALUE error");
321	}
322
323	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,			/* samples */
324							   GL_RGBA8, gl_max_texture_size_value + 1, /* width */
325							   gl_max_texture_size_value + 1,			/* height */
326							   GL_TRUE);								/* fixedsamplelocations */
327
328	error_code = gl.getError();
329	if (error_code != GL_INVALID_VALUE)
330	{
331		TCU_FAIL("Invalid glTexStorage2DMultisample() call ((max texture size+1, max texture size+1) resolution) did "
332				 "not generate GL_INVALID_VALUE error");
333	}
334
335	/* Try to set up a null resolution 2D multisample TO. */
336	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
337							   GL_RGBA8, 0,					 /* width */
338							   0,							 /* height */
339							   GL_TRUE);					 /* fixedsamplelocations */
340
341	error_code = gl.getError();
342	if (error_code != GL_INVALID_VALUE)
343	{
344		TCU_FAIL(
345			"Invalid glTexStorage2DMultisample() call with a 0x0 resolution did not generate GL_INVALID_VALUE error");
346	}
347
348	/* Delete the texture object before we continue */
349	gl.deleteTextures(1, &to_id);
350
351	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures() failed");
352
353	/* Create a new texture object and bind it to 2D multisample texture target. */
354	gl.genTextures(1, &to_id);
355	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
356
357	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not re-create 2D multisample texture object");
358
359	/* Try to set up an invalid texture object with at least one dimension size defined as a negative value */
360	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2 /* samples */, GL_RGBA8 /* sizedinternalformat */,
361							   -1, /* width */
362							   0,  /* height */
363							   GL_TRUE /* fixedsamplelocations */);
364
365	error_code = gl.getError();
366	if (error_code != GL_INVALID_VALUE)
367	{
368		TCU_FAIL(
369			"Invalid glTexStorage2DMultisample() call ((-1, 0) resolution) did not generate GL_INVALID_VALUE error");
370	}
371
372	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
373							   GL_RGBA8, 0,					 /* width */
374							   -1,							 /* height */
375							   GL_TRUE);					 /* fixedsamplelocations */
376
377	error_code = gl.getError();
378	if (error_code != GL_INVALID_VALUE)
379	{
380		TCU_FAIL(
381			"Invalid glTexStorage2DMultisample() call ((0, -1) resolution) did not generate GL_INVALID_VALUE error");
382	}
383
384	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
385							   GL_RGBA8, -1,				 /* width */
386							   -1,							 /* height */
387							   GL_TRUE);					 /* fixedsamplelocations */
388
389	error_code = gl.getError();
390	if (error_code != GL_INVALID_VALUE)
391	{
392		TCU_FAIL(
393			"Invalid glTexStorage2DMultisample() call ((-1, -1) resolution) did not generate GL_INVALID_VALUE error");
394	}
395
396	/* Test case passed */
397	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
398
399	return STOP;
400}
401
402/** Constructor.
403 *
404 *  @param context Rendering context handle.
405 **/
406MultisampleTextureTexStorage2DNonColorDepthOrStencilInternalFormatsTest::
407	MultisampleTextureTexStorage2DNonColorDepthOrStencilInternalFormatsTest(Context& context)
408	: TestCase(context, "multisample_texture_tex_storage_2d_non_color_depth_or_stencil_internal_formats_rejected",
409			   "Verifies TexStorage2DMultisample() rejects internal formats that "
410			   "are not color-renderable, depth-renderable and stencil-renderable")
411	, to_id(0)
412{
413	/* Left blank on purpose */
414}
415
416/** Deinitializes ES objects created during test execution */
417void MultisampleTextureTexStorage2DNonColorDepthOrStencilInternalFormatsTest::deinit()
418{
419	/* Delete texture in case the test case failed */
420	deinitInternalIteration();
421
422	/* Call base class deinitialization routine */
423	glcts::TestCase::deinit();
424}
425
426/** Deinitializes GL ES objects specific to internal iteration */
427void MultisampleTextureTexStorage2DNonColorDepthOrStencilInternalFormatsTest::deinitInternalIteration()
428{
429	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
430
431	if (to_id != 0)
432	{
433		/* Delete texture object */
434		gl.deleteTextures(1, &to_id);
435
436		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete texture object");
437
438		to_id = 0;
439	}
440
441	/* Unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE texture target */
442	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
443
444	GLU_EXPECT_NO_ERROR(gl.getError(),
445						"Failed to unbind a texture object from GL_TEXTURE_2D_MULTISAMPLE texture target");
446}
447
448/** Initializes GL ES objects specific to internal iteration */
449void MultisampleTextureTexStorage2DNonColorDepthOrStencilInternalFormatsTest::initInternalIteration()
450{
451	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
452
453	/* Generate texture object id */
454	gl.genTextures(1, &to_id);
455
456	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed to generate texture");
457
458	/* Verify texture object has been generated properly */
459	if (to_id == 0)
460	{
461		TCU_FAIL("Texture object has not been generated properly");
462	}
463
464	/* Bind generated texture object ID to GL_TEXTURE_2D_MULTISAMPLE texture target */
465	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
466
467	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() reported an error");
468}
469
470/** Executes test iteration.
471 *
472 *  @return Always STOP.
473 */
474tcu::TestNode::IterateResult MultisampleTextureTexStorage2DNonColorDepthOrStencilInternalFormatsTest::iterate()
475{
476	/* Test case variables */
477	const glw::GLboolean  fixedsamplelocations = GL_TRUE;
478	const glw::Functions& gl				   = m_context.getRenderContext().getFunctions();
479	const glw::GLsizei	height			   = 1;
480	/* GL_SRGB8_ALPHA8 is renderable according to spec - replaced with GL_SRGB8 */
481	/* GL_RGBA32F is renderable if EXT_color_buffer_float extension is supported - replaced with GL_RGB32F */
482	/* GL_SRGB8 is renderable if extension NV_sRGB_formats is supported. */
483	/* GL_R8_SNORM is renderable if extension EXT_render_snorm is supported - replace with GL_RGB8_SNORM*/
484	const glw::GLenum  internalformats_list[]	 = { GL_RGB8_SNORM, GL_RGB32F, GL_RGB32I };
485	const int		   internalformats_list_count = sizeof(internalformats_list) / sizeof(internalformats_list[0]);
486	const glw::GLsizei samples					  = 1;
487	const glw::GLenum  target					  = GL_TEXTURE_2D_MULTISAMPLE;
488	const glw::GLsizei width					  = 1;
489
490	/* Iterate through all internal formats test case should check */
491	for (int i = 0; i < internalformats_list_count; i++)
492	{
493		/* Initialize texture object and bind it to GL_TEXTURE_2D_MULTISAMPLE target */
494		initInternalIteration();
495
496		/* Issue call with valid parameters, but invalid internalformats */
497		gl.texStorage2DMultisample(target, samples, internalformats_list[i], width, height, fixedsamplelocations);
498
499		/* Check if the expected error code was reported */
500		if (gl.getError() != GL_INVALID_ENUM)
501		{
502			TCU_FAIL("Invalid error code reported");
503		}
504
505		/* Deinitialize texture object and unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE target */
506		deinitInternalIteration();
507	}
508
509	/* Test case passed */
510	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
511
512	return STOP;
513}
514
515/** Constructor.
516 *
517 *  @param context Rendering context handle.
518 **/
519MultisampleTextureTexStorage2DReconfigurationRejectedTest::MultisampleTextureTexStorage2DReconfigurationRejectedTest(
520	Context& context)
521	: TestCase(context, "multisample_texture_tex_storage_2d_reconfiguration_rejected",
522			   "Verifies TexStorage2DMultisample() reconfiguration fails")
523	, gl_oes_texture_storage_multisample_2d_array_supported(GL_FALSE)
524	, to_id_2d(0)
525	, to_id_2d_array(0)
526{
527	/* Left blank on purpose */
528}
529
530/** Deinitializes ES objects created during test execution */
531void MultisampleTextureTexStorage2DReconfigurationRejectedTest::deinit()
532{
533	/* Delete texture and bind default texture to GL_TEXTURE_2D_MULTISAMPLE */
534	deinitTexture(to_id_2d, GL_TEXTURE_2D_MULTISAMPLE);
535
536	if (gl_oes_texture_storage_multisample_2d_array_supported)
537	{
538		/* Delete texture and bind default texture to GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES */
539		deinitTexture(to_id_2d_array, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES);
540	}
541	/* Call base class' deinit() */
542	TestCase::deinit();
543}
544
545/** Deinitializes texture: delete texture and release texture object bound to specified target.
546 *
547 * @param to_id          Texture object to delete & unbind. Will be set to 0 afterward
548 * @param texture_target Target from which the texture will be unbound
549 */
550void MultisampleTextureTexStorage2DReconfigurationRejectedTest::deinitTexture(glw::GLuint& to_id,
551																			  glw::GLenum  texture_target)
552{
553	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
554
555	/* Unbind texture object bound to texture_target target */
556	gl.bindTexture(texture_target, 0);
557
558	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind a texture object");
559
560	/* Delete texture object */
561	gl.deleteTextures(1, &to_id);
562
563	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete texture object");
564
565	to_id = 0;
566}
567
568/** Initializes ES objects required for test execution */
569void MultisampleTextureTexStorage2DReconfigurationRejectedTest::initInternals()
570{
571	/* Generate and bind texture to GL_TEXTURE_2D_MULTISAMPLE target */
572	initTexture(to_id_2d, GL_TEXTURE_2D_MULTISAMPLE);
573
574	if (gl_oes_texture_storage_multisample_2d_array_supported)
575	{
576		/* Generate and bind texture to GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES target */
577		initTexture(to_id_2d_array, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES);
578	}
579}
580
581/** Initializes texture: creates texture object and binds it to specified texture target.
582 *
583 * @param to_id          Will be set to new texture object's id
584 * @param texture_target Texture target, to which the created texture should be bound to
585 */
586void MultisampleTextureTexStorage2DReconfigurationRejectedTest::initTexture(glw::GLuint& to_id,
587																			glw::GLenum  texture_target)
588{
589	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
590
591	/* Generate texture object id */
592	gl.genTextures(1, &to_id);
593
594	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed to generate texture");
595
596	/* Verify texture object has been generated properly */
597	if (to_id == 0)
598	{
599		TCU_FAIL("Texture object has not been generated properly");
600	}
601
602	/* Bind generated texture object ID to texture_target target */
603	gl.bindTexture(texture_target, to_id);
604
605	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() reported an error");
606}
607
608/** Executes test iteration.
609 *
610 *  @return Always STOP.
611 */
612tcu::TestNode::IterateResult MultisampleTextureTexStorage2DReconfigurationRejectedTest::iterate()
613{
614	gl_oes_texture_storage_multisample_2d_array_supported =
615		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
616
617	initInternals();
618
619	/* Test case variables */
620	const glw::GLsizei   depth				  = 4;
621	const glw::GLboolean fixedsamplelocations = GL_TRUE;
622	const glw::GLsizei   height				  = 4;
623	const glw::GLenum	internalformat		  = GL_RGBA8;
624	const glw::GLsizei   samples			  = 2;
625	const glw::GLsizei   width				  = 4;
626
627	/* Set up immutable 2D multisample texture object */
628	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
629
630	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, width, height, fixedsamplelocations);
631
632	GLU_EXPECT_NO_ERROR(gl.getError(),
633						"glTexStorage2DMultisample() failed to set up immutable 2D multisample texture object");
634
635	/* Try to reset immutable 2D multisample texture object */
636	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, internalformat, width, height, fixedsamplelocations);
637
638	if (gl.getError() != GL_INVALID_OPERATION)
639	{
640		TCU_FAIL("Invalid error code reported");
641	}
642
643	if (gl_oes_texture_storage_multisample_2d_array_supported)
644	{
645		/* Set up immutable 2D array multisample texture object */
646		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samples, internalformat, width, height, depth,
647								   fixedsamplelocations);
648
649		GLU_EXPECT_NO_ERROR(
650			gl.getError(),
651			"gltexStorage3DMultisample() failed to set up immutable 2D array multisample texture object");
652
653		/* Try to reset immutable 2D array multisample texture object */
654		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, samples, internalformat, width, height, depth,
655								   fixedsamplelocations);
656
657		if (gl.getError() != GL_INVALID_OPERATION)
658		{
659			TCU_FAIL("Invalid error code reported");
660		}
661	}
662
663	/* Test case passed */
664	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
665
666	return STOP;
667}
668
669/** Constructor.
670 *
671 *  @param context Rendering context handle.
672 **/
673MultisampleTextureTexStorage2DTexture2DMultisampleArrayTest::
674	MultisampleTextureTexStorage2DTexture2DMultisampleArrayTest(Context& context)
675	: TestCase(context, "multisample_texture_tex_storage_2d_texture_2d_multsample_array",
676			   "Verifies TexStorage2DMultisample() rejects GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES targets")
677{
678	/* Left blank on purpose */
679}
680
681/** Executes test iteration.
682 *
683 *  @return Always STOP.
684 */
685tcu::TestNode::IterateResult MultisampleTextureTexStorage2DTexture2DMultisampleArrayTest::iterate()
686{
687	/* NOTE: This test can be executed, no matter whether GL_OES_texture_storage_multisample_2d_array
688	 *       extension is supported on the running platform, or not.
689	 */
690	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
691
692	/* Issue call with valid parameters and GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES target */
693	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 1, GL_RGBA8, 1, 1, false);
694
695	/* Check if the expected error code was reported */
696	if (gl.getError() != GL_INVALID_ENUM)
697	{
698		TCU_FAIL("Invalid error code reported");
699	}
700
701	/* Test case passed */
702	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
703
704	return STOP;
705}
706
707/** Constructor.
708 *
709 *  @param context Rendering context handle.
710 **/
711MultisampleTextureTexStorage2DUnsupportedSamplesCountForColorTexturesTest::
712	MultisampleTextureTexStorage2DUnsupportedSamplesCountForColorTexturesTest(Context& context)
713	: TestCase(context, "multisample_texture_tex_storage_2d_unsupported_samples_count_for_color_textures_rejected",
714			   "Verifies TexStorage2DMultisample() rejects requests to set up "
715			   "multisample color textures with unsupported number of samples")
716	, to_id(0)
717{
718	/* Left blank on purpose */
719}
720
721/** Deinitializes ES objects created during test execution */
722void MultisampleTextureTexStorage2DUnsupportedSamplesCountForColorTexturesTest::deinit()
723{
724	/* Delete texture in case the test case failed */
725	deinitInternalIteration();
726
727	/* Call base class deinitialization routine */
728	glcts::TestCase::deinit();
729}
730
731/** Deinitializes GL ES objects specific to internal iteration */
732void MultisampleTextureTexStorage2DUnsupportedSamplesCountForColorTexturesTest::deinitInternalIteration()
733{
734	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
735
736	if (to_id != 0)
737	{
738		/* Delete texture object */
739		gl.deleteTextures(1, &to_id);
740
741		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete texture object");
742
743		to_id = 0;
744	}
745
746	/* Unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE texture target */
747	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
748
749	GLU_EXPECT_NO_ERROR(gl.getError(),
750						"Failed to unbind a texture object from GL_TEXTURE_2D_MULTISAMPLE texture target");
751}
752
753/** Initializes GL ES objects specific to internal iteration */
754void MultisampleTextureTexStorage2DUnsupportedSamplesCountForColorTexturesTest::initInternalIteration()
755{
756	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
757
758	/* Generate texture object id */
759	gl.genTextures(1, &to_id);
760
761	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed to generate texture");
762
763	/* Verify texture object has been generated properly */
764	if (to_id == 0)
765	{
766		TCU_FAIL("Texture object has not been generated properly");
767	}
768
769	/* Bind generated texture object ID to GL_TEXTURE_2D_MULTISAMPLE texture target */
770	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
771
772	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() reported an error");
773}
774
775/** Executes test iteration.
776 *
777 *  @return Always STOP.
778 */
779tcu::TestNode::IterateResult MultisampleTextureTexStorage2DUnsupportedSamplesCountForColorTexturesTest::iterate()
780{
781	/* Test case variables */
782	const glw::Functions& gl						  = m_context.getRenderContext().getFunctions();
783	const glw::GLsizei	height					  = 1;
784	const glw::GLboolean  fixedsamplelocations_list[] = { GL_FALSE, GL_TRUE };
785	const int			  fixedsamplelocations_list_count =
786		sizeof(fixedsamplelocations_list) / sizeof(fixedsamplelocations_list[0]);
787	glw::GLint		   gl_max_color_texture_samples_value  = -1; /* Will be determined later */
788	glw::GLint		   gl_max_internalformat_samples_value = -1; /* Will be determined later */
789	glw::GLint		   gl_max_samples_value				   = -1; /* Will be determined later */
790	const glw::GLenum  internalformat_list[]	 = { GL_R8, GL_RGB565, GL_RGB10_A2UI, GL_SRGB8_ALPHA8, GL_R8I };
791	const int		   internalformat_list_count = sizeof(internalformat_list) / sizeof(internalformat_list[0]);
792	const glw::GLenum  target = GL_TEXTURE_2D_MULTISAMPLE; /* Test case uses GL_TEXTURE_2D_MULTISAMPLE target */
793	const glw::GLsizei width  = 1;
794
795	/* Iterate through all internal formats test case should check */
796	for (int internalformat_index = 0; internalformat_index < internalformat_list_count; internalformat_index++)
797	{
798		/* Iteration-specific internalformat */
799		glw::GLenum internalformat = internalformat_list[internalformat_index];
800
801		/* Iterate through all fixedsamplelocations test case should check */
802		for (int fixedsamplelocations_index = 0; fixedsamplelocations_index < fixedsamplelocations_list_count;
803			 fixedsamplelocations_index++)
804		{
805			/* Iteration-specific fixedsamplelocations */
806			glw::GLboolean fixedsamplelocations = fixedsamplelocations_list[fixedsamplelocations_index];
807
808			/* Initialize texture object and bind it to GL_TEXTURE_2D_MULTISAMPLE target */
809			initInternalIteration();
810
811			/* Get GL_MAX_SAMPLES value */
812			gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
813
814			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_MAX_SAMPLES value");
815
816			/* Get GL_MAX_COLOR_TEXTURE_SAMPLES value */
817			gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &gl_max_color_texture_samples_value);
818
819			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_MAX_COLOR_TEXTURE_SAMPLES value");
820
821			/* Retrieve maximum amount of samples available for the texture target considered */
822			gl.getInternalformativ(target, internalformat, GL_SAMPLES, 1, &gl_max_internalformat_samples_value);
823
824			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed to retrieve GL_SAMPLES");
825
826			/* Issue call with valid parameters, but samples argument might be invalid */
827			gl.texStorage2DMultisample(target, gl_max_internalformat_samples_value + 1, internalformat, width, height,
828									   fixedsamplelocations);
829
830			/* Expect GL_INVALID_OPERATION error code. */
831			TCU_CHECK_MSG(gl.getError() == GL_INVALID_OPERATION,
832						  "glTexStorage2DMultisample() did not generate GL_INVALID_OPERATION error.");
833
834			/* Issue call with valid parameters, but to another target GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES and with invalid samples.
835			 *
836			 * NOTE: This can be executed on both the implementations that support GL_OES_texture_storage_multisample_2d_array extension
837			 *       and on those that don't.
838			 */
839			gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, gl_max_internalformat_samples_value + 1,
840									   internalformat, width, height, fixedsamplelocations);
841
842			/* Expect GL_INVALID_ENUM error code from invalid target. */
843			TCU_CHECK_MSG(gl.getError() == GL_INVALID_ENUM,
844						  "glTexStorage2DMultisample() did not generate GL_INVALID_ENUM error.");
845
846			/* Deinitialize texture object and unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE target */
847			deinitInternalIteration();
848		}
849	}
850
851	/* Test case passed */
852	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
853
854	return STOP;
855}
856
857/** Constructor.
858 *
859 *  @param context Rendering context handle.
860 **/
861MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthTexturesTest::
862	MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthTexturesTest(Context& context)
863	: TestCase(context, "multisample_texture_tex_storage_2d_unsupported_samples_count_for_depth_textures_rejected",
864			   "Verifies TexStorage2DMultisample() rejects requests to set up multisample "
865			   "depth textures with unsupported number of samples")
866	, to_id(0)
867{
868	/* Left blank on purpose */
869}
870
871/** Deinitializes ES objects created during test execution */
872void MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthTexturesTest::deinit()
873{
874	/* Delete texture in case the test case failed */
875	deinitInternalIteration();
876
877	/* Call base class deinitialization routine */
878	glcts::TestCase::deinit();
879}
880
881/** Deinitializes GL ES objects specific to internal iteration */
882void MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthTexturesTest::deinitInternalIteration()
883{
884	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
885
886	if (to_id != 0)
887	{
888		/* Delete texture object */
889		gl.deleteTextures(1, &to_id);
890
891		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete texture object");
892
893		to_id = 0;
894	}
895
896	/* Unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE texture target */
897	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
898
899	GLU_EXPECT_NO_ERROR(gl.getError(),
900						"Failed to unbind a texture object from GL_TEXTURE_2D_MULTISAMPLE texture target");
901}
902
903/** Initializes GL ES objects specific to internal iteration */
904void MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthTexturesTest::initInternalIteration()
905{
906	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
907
908	/* Generate texture object id */
909	gl.genTextures(1, &to_id);
910
911	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed to generate texture");
912
913	/* Verify texture object has been generated properly */
914	if (to_id == 0)
915	{
916		TCU_FAIL("Texture object has not been generated properly");
917	}
918
919	/* Bind generated texture object ID to GL_TEXTURE_2D_MULTISAMPLE texture target */
920	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
921
922	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() reported an error");
923}
924
925/** Executes test iteration.
926 *
927 *  @return Always STOP.
928 */
929tcu::TestNode::IterateResult MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthTexturesTest::iterate()
930{
931	/* Test case variables */
932	const glw::GLboolean fixedsamplelocations_list[] = { GL_FALSE, GL_TRUE };
933	const int			 fixedsamplelocations_list_count =
934		sizeof(fixedsamplelocations_list) / sizeof(fixedsamplelocations_list[0]);
935	const glw::Functions& gl								  = m_context.getRenderContext().getFunctions();
936	glw::GLint			  gl_max_depth_texture_samples_value  = -1; /* Will be determined later */
937	glw::GLint			  gl_max_internalformat_samples_value = -1; /* Will be determined later */
938	glw::GLint			  gl_max_samples_value				  = -1; /* Will be determined later */
939	const glw::GLsizei	height							  = 1;
940	const glw::GLenum	 internalformat_list[] = { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8 };
941	const int			  internalformat_list_count = sizeof(internalformat_list) / sizeof(internalformat_list[0]);
942	const glw::GLenum	 target = GL_TEXTURE_2D_MULTISAMPLE; /* Test case uses GL_TEXTURE_2D_MULTISAMPLE target */
943	const glw::GLsizei	width  = 1;
944
945	/* Iterate through all internal formats test case should check */
946	for (int internalformat_index = 0; internalformat_index < internalformat_list_count; internalformat_index++)
947	{
948		/* Iteration-specific internalformat */
949		glw::GLenum internalformat = internalformat_list[internalformat_index];
950
951		/* Iterate through all fixedsamplelocations test case should check */
952		for (int fixedsamplelocations_index = 0; fixedsamplelocations_index < fixedsamplelocations_list_count;
953			 fixedsamplelocations_index++)
954		{
955			/* Iteration-specific fixedsamplelocations */
956			glw::GLboolean fixedsamplelocations = fixedsamplelocations_list[fixedsamplelocations_index];
957
958			/* Initialize texture object and bind it to GL_TEXTURE_2D_MULTISAMPLE target */
959			initInternalIteration();
960
961			/* Get GL_MAX_SAMPLES value */
962			gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
963
964			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_MAX_SAMPLES value");
965
966			/* Get GL_MAX_DEPTH_TEXTURE_SAMPLES value */
967			gl.getIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &gl_max_depth_texture_samples_value);
968
969			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_MAX_DEPTH_TEXTURE_SAMPLES value");
970
971			/* Retrieve maximum amount of samples available for the texture target considered */
972			gl.getInternalformativ(target, internalformat, GL_SAMPLES, 1, &gl_max_internalformat_samples_value);
973
974			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed to retrieve GL_SAMPLES");
975
976			/* Issue call with valid parameters, but samples argument might be invalid */
977			gl.texStorage2DMultisample(target, gl_max_internalformat_samples_value + 1, internalformat, width, height,
978									   fixedsamplelocations);
979
980			/* Expect GL_INVALID_OPERATION error code. */
981			TCU_CHECK_MSG(gl.getError() == GL_INVALID_OPERATION,
982						  "glTexStorage2DMultisample() did not generate GL_INVALID_OPERATION error.");
983
984			/* Deinitialize texture object and unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE target */
985			deinitInternalIteration();
986		}
987	}
988
989	/* Test case passed */
990	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
991
992	return STOP;
993}
994
995/** Constructor.
996 *
997 *  @param context Rendering context handle.
998 **/
999MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthStencilTexturesTest::
1000	MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthStencilTexturesTest(Context& context)
1001	: TestCase(context,
1002			   "multisample_texture_tex_storage_2d_unsupported_samples_count_for_depth_stencil_textures_rejected",
1003			   "Verifies TexStorage2DMultisample() rejects requests to set up multisample "
1004			   "depth+stencil textures with unsupported number of samples")
1005	, to_id(0)
1006{
1007	/* Left blank on purpose */
1008}
1009
1010/** Deinitializes ES objects created during test execution */
1011void MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthStencilTexturesTest::deinit()
1012{
1013	/* Delete texture in case the test case failed */
1014	deinitInternalIteration();
1015
1016	/* Call base class deinitialization routine */
1017	glcts::TestCase::deinit();
1018}
1019
1020/** Deinitializes GL ES objects specific to internal iteration */
1021void MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthStencilTexturesTest::deinitInternalIteration()
1022{
1023	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1024
1025	if (to_id != 0)
1026	{
1027		/* Delete texture object */
1028		gl.deleteTextures(1, &to_id);
1029
1030		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete texture object");
1031
1032		to_id = 0;
1033	}
1034
1035	/* Unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE texture target */
1036	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
1037
1038	GLU_EXPECT_NO_ERROR(gl.getError(),
1039						"Failed to unbind a texture object from GL_TEXTURE_2D_MULTISAMPLE texture target");
1040}
1041
1042/** Initializes GL ES objects specific to internal iteration */
1043void MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthStencilTexturesTest::initInternalIteration()
1044{
1045	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1046
1047	/* Generate texture object id */
1048	gl.genTextures(1, &to_id);
1049
1050	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed to generate texture");
1051
1052	/* Verify texture object has been generated properly */
1053	if (to_id == 0)
1054	{
1055		TCU_FAIL("Texture object has not been generated properly");
1056	}
1057
1058	/* Bind generated texture object ID to GL_TEXTURE_2D_MULTISAMPLE texture target */
1059	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1060
1061	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() reported an error");
1062}
1063
1064/** Executes test iteration.
1065 *
1066 *  @return Always STOP.
1067 */
1068tcu::TestNode::IterateResult MultisampleTextureTexStorage2DUnsupportedSamplesCountForDepthStencilTexturesTest::iterate()
1069{
1070	/* Test case variables */
1071	const glw::GLboolean fixedsamplelocations_list[] = { GL_FALSE, GL_TRUE };
1072	const int			 fixedsamplelocations_list_count =
1073		sizeof(fixedsamplelocations_list) / sizeof(fixedsamplelocations_list[0]);
1074	const glw::Functions& gl								  = m_context.getRenderContext().getFunctions();
1075	glw::GLint			  gl_max_depth_texture_samples_value  = -1; /* Will be determined later */
1076	glw::GLint			  gl_max_internalformat_samples_value = -1; /* Will be determined later */
1077	glw::GLint			  gl_max_samples_value				  = -1; /* Will be determined later */
1078	const glw::GLsizei	height							  = 1;
1079	const glw::GLenum	 internalformat_list[]				  = { GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8 };
1080	const int			  internalformat_list_count = sizeof(internalformat_list) / sizeof(internalformat_list[0]);
1081	const glw::GLenum	 target = GL_TEXTURE_2D_MULTISAMPLE; /* Test case uses GL_TEXTURE_2D_MULTISAMPLE target */
1082	const glw::GLsizei	width  = 1;
1083
1084	/* Iterate through all internal formats test case should check */
1085	for (int internalformat_index = 0; internalformat_index < internalformat_list_count; internalformat_index++)
1086	{
1087		/* Iteration-specific internalformat */
1088		glw::GLenum internalformat = internalformat_list[internalformat_index];
1089
1090		/* Iterate through all fixedsamplelocations test case should check */
1091		for (int fixedsamplelocations_index = 0; fixedsamplelocations_index < fixedsamplelocations_list_count;
1092			 fixedsamplelocations_index++)
1093		{
1094			/* Iteration-specific fixedsamplelocations */
1095			glw::GLboolean fixedsamplelocations = fixedsamplelocations_list[fixedsamplelocations_index];
1096
1097			/* Initialize texture object and bind it to GL_TEXTURE_2D_MULTISAMPLE target */
1098			initInternalIteration();
1099
1100			/* Get GL_MAX_SAMPLES value */
1101			gl.getIntegerv(GL_MAX_SAMPLES, &gl_max_samples_value);
1102
1103			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_MAX_SAMPLES value");
1104
1105			/* Get GL_MAX_DEPTH_TEXTURE_SAMPLES value */
1106			gl.getIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &gl_max_depth_texture_samples_value);
1107
1108			GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_MAX_DEPTH_TEXTURE_SAMPLES value");
1109
1110			/* Retrieve maximum amount of samples available for the texture target considered */
1111			gl.getInternalformativ(target, internalformat, GL_SAMPLES, 1, &gl_max_internalformat_samples_value);
1112
1113			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed to retrieve GL_SAMPLES");
1114
1115			/* Issue call with valid parameters, but samples argument might be invalid */
1116			gl.texStorage2DMultisample(target, gl_max_internalformat_samples_value + 1, internalformat, width, height,
1117									   fixedsamplelocations);
1118
1119			/* Expect GL_INVALID_OPERATION error code. */
1120			TCU_CHECK_MSG(gl.getError() == GL_INVALID_OPERATION,
1121						  "glTexStorage2DMultisample() did not generate GL_INVALID_OPERATION error.");
1122
1123			/* Deinitialize texture object and unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE target */
1124			deinitInternalIteration();
1125		}
1126	}
1127
1128	/* Test case passed */
1129	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1130
1131	return STOP;
1132}
1133
1134/** Constructor.
1135 *
1136 *  @param context Rendering context handle.
1137 **/
1138MultisampleTextureTexStorage2DValidCallsTest::MultisampleTextureTexStorage2DValidCallsTest(Context& context)
1139	: TestCase(context, "multisample_texture_tex_storage_2d_valid_calls",
1140			   "Verifies TexStorage2DMultisample() does not generate an error "
1141			   "when asked to set up multisample color/depth/textures in various configurations.")
1142	, to_id(0)
1143{
1144	/* Left blank on purpose */
1145}
1146
1147/** Deinitializes ES objects created during test execution */
1148void MultisampleTextureTexStorage2DValidCallsTest::deinit()
1149{
1150	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1151
1152	/* Unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE texture target */
1153	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
1154
1155	GLU_EXPECT_NO_ERROR(gl.getError(),
1156						"Failed to unbind a texture object from GL_TEXTURE_2D_MULTISAMPLE texture target");
1157
1158	/* Delete texture object */
1159	if (to_id != 0)
1160	{
1161		gl.deleteTextures(1, &to_id);
1162		GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete texture object");
1163
1164		to_id = 0;
1165	}
1166
1167	/* Call base class deinitialization routine */
1168	glcts::TestCase::deinit();
1169}
1170
1171/** Initializes ES objects required for test execution */
1172void MultisampleTextureTexStorage2DValidCallsTest::initInternals()
1173{
1174	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1175
1176	/* Generate a texture object id */
1177	gl.genTextures(1, &to_id);
1178
1179	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed to generate a texture object ID");
1180
1181	/* Bind texture to GL_TEXTURE_2D_MULTISAMPLE texture target */
1182	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1183
1184	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
1185}
1186
1187/** Executes test iteration.
1188 *
1189 *  @return Always STOP.
1190 */
1191tcu::TestNode::IterateResult MultisampleTextureTexStorage2DValidCallsTest::iterate()
1192{
1193	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1194
1195	initInternals();
1196
1197	/* Retrieve GL_MAX_COLOR_TEXTURE_SAMPLES pname value */
1198	glw::GLint gl_max_color_texture_samples_value = 0;
1199
1200	gl.getIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &gl_max_color_texture_samples_value);
1201	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_COLOR_TEXTURE_SAMPLES pname value");
1202
1203	/* Retrieve GL_MAX_DEPTH_TEXTURE_SAMPLES pname value */
1204	glw::GLint gl_max_depth_texture_samples_value = 0;
1205
1206	gl.getIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &gl_max_depth_texture_samples_value);
1207	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not retrieve GL_MAX_DEPTH_TEXTURE_SAMPLES pname value");
1208
1209	/* Iterate through color-, depth- and stencil-renderable internalformats */
1210	const glw::GLenum  color_internalformats[]   = { GL_R8, GL_RGB565, GL_RGB10_A2UI, GL_SRGB8_ALPHA8, GL_R8I };
1211	const glw::GLenum  depth_internalformats[]   = { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT32F, GL_DEPTH24_STENCIL8 };
1212	const glw::GLenum  stencil_internalformats[] = { GL_DEPTH24_STENCIL8, GL_DEPTH32F_STENCIL8 };
1213	const unsigned int n_color_internalformats   = sizeof(color_internalformats) / sizeof(color_internalformats[0]);
1214	const unsigned int n_depth_internalformats   = sizeof(depth_internalformats) / sizeof(depth_internalformats[0]);
1215	const unsigned int n_stencil_internalformats = sizeof(stencil_internalformats) / sizeof(stencil_internalformats[0]);
1216
1217	for (unsigned int n_iteration = 0; n_iteration < 3 /* color/depth/stencil */; ++n_iteration)
1218	{
1219		const glw::GLenum* internalformats						   = NULL;
1220		glw::GLint		   max_iteration_specific_gl_samples_value = 0;
1221		unsigned int	   n_internalformats					   = 0;
1222
1223		switch (n_iteration)
1224		{
1225		case 0:
1226		{
1227			internalformats							= color_internalformats;
1228			max_iteration_specific_gl_samples_value = gl_max_color_texture_samples_value;
1229			n_internalformats						= n_color_internalformats;
1230
1231			break;
1232		}
1233
1234		case 1:
1235		{
1236			internalformats							= depth_internalformats;
1237			max_iteration_specific_gl_samples_value = gl_max_depth_texture_samples_value;
1238			n_internalformats						= n_depth_internalformats;
1239
1240			break;
1241		}
1242
1243		case 2:
1244		{
1245			internalformats							= stencil_internalformats;
1246			max_iteration_specific_gl_samples_value = gl_max_depth_texture_samples_value;
1247			n_internalformats						= n_stencil_internalformats;
1248
1249			break;
1250		}
1251
1252		default:
1253		{
1254			TCU_FAIL("Unrecognized iteration index");
1255		}
1256		} /* switch (n_iteration) */
1257
1258		/* Iterate through valid fixedsamplelocations argument values */
1259		const glw::GLboolean fixedsamplelocations_values[] = { GL_FALSE, GL_TRUE };
1260		const unsigned int   n_fixedsamplelocations_values =
1261			sizeof(fixedsamplelocations_values) / sizeof(fixedsamplelocations_values[0]);
1262
1263		for (unsigned int n_fixedsamplelocations_value = 0;
1264			 n_fixedsamplelocations_value < n_fixedsamplelocations_values; ++n_fixedsamplelocations_value)
1265		{
1266			glw::GLboolean fixedsamplelocations = fixedsamplelocations_values[n_fixedsamplelocations_value];
1267
1268			/* Iterate through internalformats */
1269			for (unsigned int n_internalformat = 0; n_internalformat < n_internalformats; ++n_internalformat)
1270			{
1271				glw::GLenum internalformat			   = internalformats[n_internalformat];
1272				glw::GLint  internalformat_max_samples = 0;
1273
1274				/* Retrieve internalformat-specific GL_MAX_SAMPLES value */
1275				gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE,	 /* target */
1276									   internalformat, GL_SAMPLES, 1, /* bufSize */
1277									   &internalformat_max_samples);
1278
1279				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetInternalformativ() failed");
1280
1281				/* Determine maximum amount of samples we can use for the test*/
1282				glw::GLint max_samples =
1283					de::max(1, de::min(internalformat_max_samples, max_iteration_specific_gl_samples_value));
1284
1285				/* Iterate through all valid samples argument values */
1286				for (int n_samples = 1; n_samples <= max_samples; ++n_samples)
1287				{
1288					gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, n_samples, internalformat, 1, /* width */
1289											   1,														/* height */
1290											   fixedsamplelocations); /* fixedsamplelocations */
1291
1292					GLU_EXPECT_NO_ERROR(gl.getError(), "A valid glTexStorage2DMultisample() call failed");
1293
1294					/* Re-create the texture object before we continue */
1295					gl.deleteTextures(1, &to_id);
1296					gl.genTextures(1, &to_id);
1297
1298					gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1299
1300					GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to re-create a texture object");
1301				} /* for (all samples argument values) */
1302			}	 /* for (all color-renderable internalformats) */
1303		}		  /* for (all fixedsamplelocations argument values) */
1304	}			  /* for (all iterations) */
1305
1306	/* Test case passed */
1307	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1308
1309	return STOP;
1310}
1311
1312/** Constructor.
1313 *
1314 *  @param context Rendering context handle.
1315 **/
1316MultisampleTextureTexStorage2DZeroSampleTest::MultisampleTextureTexStorage2DZeroSampleTest(Context& context)
1317	: TestCase(context, "multisample_texture_tex_storage_2d_zero_sample",
1318			   "Verifies TexStorage2DMultisample() rejects zero "
1319			   "sample requests by generating a GL_INVALID_VALUE error.")
1320	, to_id(0)
1321{
1322	/* Left blank on purpose */
1323}
1324
1325/** Deinitializes ES objects created during test execution */
1326void MultisampleTextureTexStorage2DZeroSampleTest::deinit()
1327{
1328	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1329
1330	/* Unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE texture target */
1331	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
1332
1333	GLU_EXPECT_NO_ERROR(gl.getError(),
1334						"Failed to unbind a texture object from GL_TEXTURE_2D_MULTISAMPLE texture target");
1335
1336	/* Delete texture object */
1337	gl.deleteTextures(1, &to_id);
1338
1339	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete texture object");
1340
1341	to_id = 0;
1342
1343	/* Call base class deinitialization routine */
1344	glcts::TestCase::deinit();
1345}
1346
1347/** Initializes ES objects required for test execution */
1348void MultisampleTextureTexStorage2DZeroSampleTest::initInternals()
1349{
1350	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1351
1352	/* Generate texture object id */
1353	gl.genTextures(1, &to_id);
1354
1355	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed to generate texture");
1356
1357	/* Verify texture object has been generated properly */
1358	if (to_id == 0)
1359	{
1360		TCU_FAIL("Texture object has not been generated properly");
1361	}
1362
1363	/* Bind texture to GL_TEXTURE_2D_MULTISAMPLE */
1364	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id);
1365
1366	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() reported an error");
1367}
1368
1369/** Executes test iteration.
1370 *
1371 *  @return Always STOP.
1372 */
1373tcu::TestNode::IterateResult MultisampleTextureTexStorage2DZeroSampleTest::iterate()
1374{
1375	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1376
1377	initInternals();
1378
1379	/* Issue call function for target GL_TEXTURE_2D_MULTISAMPLE, but provide zero for samples argument */
1380	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 0, GL_RGBA8, 1, 1, true);
1381
1382	/* Check if the expected error code was reported */
1383	glw::GLenum error_code = gl.getError();
1384
1385	if (error_code != GL_INVALID_VALUE)
1386	{
1387		TCU_FAIL("Invalid error code reported");
1388	}
1389
1390	/* Test case passed */
1391	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1392
1393	return STOP;
1394}
1395
1396} /* glcts namespace */
1397