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  es31cTextureStorageMultisampleGLCoverageTests.cpp
27 * \brief Implements coverage tests for multisample textures. (ES3.1 only)
28 */ /*-------------------------------------------------------------------*/
29
30#include "es31cTextureStorageMultisampleGLCoverageTests.hpp"
31#include "gluContextInfo.hpp"
32#include "gluDefs.hpp"
33#include "glwEnums.hpp"
34#include "glwFunctions.hpp"
35#include "tcuRenderTarget.hpp"
36#include "tcuTestLog.hpp"
37
38#include <string>
39#include <vector>
40
41namespace glcts
42{
43/** Constructor.
44 *
45 *  @param context Rendering context handle.
46 **/
47GLCoverageExtensionSpecificEnumsAreRecognizedTest::GLCoverageExtensionSpecificEnumsAreRecognizedTest(Context& context)
48	: TestCase(context, "extension_specific_enums_are_recognized",
49			   "GL_MAX_SAMPLE_MASK_WORDS, GL_MAX_COLOR_TEXTURE_SAMPLES, GL_MAX_DEPTH_TEXTURE_SAMPLES"
50			   ", GL_MAX_INTEGER_SAMPLES, GL_TEXTURE_BINDING_2D_MULTISAMPLE and"
51			   " GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES enums are recognized.")
52	, gl_oes_texture_storage_multisample_2d_array_supported(GL_FALSE)
53	, to_id_2d_multisample(0)
54	, to_id_2d_multisample_array(0)
55{
56	/* Left blank on purpose */
57}
58
59/* Deinitializes ES objects that may have been created while the test executed. */
60void GLCoverageExtensionSpecificEnumsAreRecognizedTest::deinit()
61{
62	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
63
64	if (to_id_2d_multisample != 0)
65	{
66		gl.deleteTextures(1, &to_id_2d_multisample);
67
68		to_id_2d_multisample = 0;
69	}
70
71	if (to_id_2d_multisample_array != 0)
72	{
73		gl.deleteTextures(1, &to_id_2d_multisample_array);
74
75		to_id_2d_multisample_array = 0;
76	}
77
78	/* Call base class' deinit() */
79	TestCase::deinit();
80}
81
82/** Executes test iteration.
83 *
84 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
85 */
86tcu::TestNode::IterateResult GLCoverageExtensionSpecificEnumsAreRecognizedTest::iterate()
87{
88	gl_oes_texture_storage_multisample_2d_array_supported =
89		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
90
91	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
92
93	/* Iterate through all pnames that need to be verified */
94	const glw::GLenum pnames[] = { GL_MAX_SAMPLE_MASK_WORDS, GL_MAX_COLOR_TEXTURE_SAMPLES, GL_MAX_DEPTH_TEXTURE_SAMPLES,
95								   GL_MAX_INTEGER_SAMPLES };
96	const unsigned int n_pnames = sizeof(pnames) / sizeof(pnames[0]);
97
98	for (unsigned int n_pname = 0; n_pname < n_pnames; ++n_pname)
99	{
100		const float epsilon = (float)1e-5;
101		glw::GLenum pname   = pnames[n_pname];
102
103		/* Test glGetIntegerv() */
104		glw::GLint int_value = -1;
105
106		gl.getIntegerv(pname, &int_value);
107		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() reported an error for a valid pname");
108
109		if (int_value < 1)
110		{
111			m_testCtx.getLog() << tcu::TestLog::Message << "An invalid integer value " << int_value
112							   << " was reported for pname [" << pname << "]." << tcu::TestLog::EndMessage;
113
114			TCU_FAIL("Invalid integer value reported for pname.");
115		}
116
117		/* Test glGetBooleanv() */
118		glw::GLboolean bool_value = GL_TRUE;
119
120		gl.getBooleanv(pname, &bool_value);
121		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv() reported an error for a valid pname");
122
123		if ((int_value != 0 && bool_value == GL_FALSE) || (int_value == 0 && bool_value != GL_FALSE))
124		{
125			m_testCtx.getLog() << tcu::TestLog::Message << "An invalid boolean value [" << bool_value << "]"
126							   << " was reported for pname [" << pname << "]"
127							   << " (integer value reported for the same property:" << int_value << ")"
128							   << tcu::TestLog::EndMessage;
129
130			TCU_FAIL("Invalid boolean value reported for pname.");
131		}
132
133		/* Test glGetFloatv() */
134		glw::GLfloat float_value = -1.0f;
135
136		gl.getFloatv(pname, &float_value);
137		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() reported an error for a valid pname");
138
139		if (de::abs(float_value - float(int_value)) > epsilon)
140		{
141			m_testCtx.getLog() << tcu::TestLog::Message << "An invalid floating-point value [" << float_value << "]"
142							   << " was reported for pname        [" << pname << "]"
143							   << " (integer value reported for the same property:" << int_value << ")"
144							   << tcu::TestLog::EndMessage;
145
146			TCU_FAIL("Invalid floating-point value reported for pname.");
147		}
148	} /* for (all pnames) */
149
150	/* Verify default multisample texture bindings are valid */
151	glw::GLboolean bool_value  = GL_TRUE;
152	const float	epsilon	 = (float)1e-5;
153	glw::GLfloat   float_value = 1.0f;
154	glw::GLint	 int_value   = 1;
155
156	gl.getBooleanv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &bool_value);
157	gl.getFloatv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &float_value);
158	gl.getIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &int_value);
159
160	GLU_EXPECT_NO_ERROR(gl.getError(),
161						"GL_TEXTURE_BINDING_2D_MULTISAMPLE pname was not recognized by one of the glGet*() functions");
162
163	if (bool_value != GL_FALSE || de::abs(float_value) > epsilon || int_value != 0)
164	{
165		TCU_FAIL("Default GL_TEXTURE_BINDING_2D_MULTISAMPLE value is invalid");
166	}
167
168	if (gl_oes_texture_storage_multisample_2d_array_supported)
169	{
170		bool_value  = GL_TRUE;
171		float_value = 1.0f;
172		int_value   = 1;
173
174		gl.getBooleanv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES, &bool_value);
175		gl.getFloatv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES, &float_value);
176		gl.getIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES, &int_value);
177
178		GLU_EXPECT_NO_ERROR(
179			gl.getError(),
180			"GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES pname was not recognized by one of the glGet*() functions");
181
182		if (bool_value != GL_FALSE || de::abs(float_value) > epsilon || int_value != 0)
183		{
184			TCU_FAIL("Default GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES value is invalid");
185		}
186	}
187
188	/* Generate two texture objects we will later bind to multisample texture targets to
189	 * verify the values reported for corresponding pnames have also changed.
190	 */
191	gl.genTextures(1, &to_id_2d_multisample);
192
193	if (gl_oes_texture_storage_multisample_2d_array_supported)
194	{
195		gl.genTextures(1, &to_id_2d_multisample_array);
196	}
197
198	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() failed");
199
200	/* Now bind the IDs to relevant texture targets */
201	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d_multisample);
202
203	if (gl_oes_texture_storage_multisample_2d_array_supported)
204	{
205		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_2d_multisample_array);
206	}
207
208	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() failed");
209
210	/* Verify new bindings are reported */
211	bool_value  = GL_FALSE;
212	float_value = 0.0f;
213	int_value   = 0;
214
215	gl.getBooleanv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &bool_value);
216	gl.getFloatv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &float_value);
217	gl.getIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE, &int_value);
218
219	GLU_EXPECT_NO_ERROR(gl.getError(),
220						"GL_TEXTURE_BINDING_2D_MULTISAMPLE pname was not recognized by one of the glGet*() functions");
221
222	glw::GLfloat expected_float_value = float(to_id_2d_multisample);
223
224	if (bool_value != GL_TRUE || de::abs(float_value - expected_float_value) > epsilon ||
225		(glw::GLuint)int_value != to_id_2d_multisample)
226	{
227		TCU_FAIL("GL_TEXTURE_BINDING_2D_MULTISAMPLE value is invalid");
228	}
229
230	if (gl_oes_texture_storage_multisample_2d_array_supported)
231	{
232		bool_value  = GL_FALSE;
233		float_value = 0.0f;
234		int_value   = 0;
235
236		gl.getBooleanv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES, &bool_value);
237		gl.getFloatv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES, &float_value);
238		gl.getIntegerv(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES, &int_value);
239
240		GLU_EXPECT_NO_ERROR(
241			gl.getError(),
242			"GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES pname was not recognized by one of the glGet*() functions");
243
244		expected_float_value = float(to_id_2d_multisample_array);
245
246		if (bool_value != GL_TRUE || de::abs(float_value - expected_float_value) > epsilon ||
247			(glw::GLuint)int_value != to_id_2d_multisample_array)
248		{
249			TCU_FAIL("GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES value is invalid");
250		}
251	}
252
253	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
254	return STOP;
255}
256
257/** Constructor.
258 *
259 *  @param context Rendering context handle.
260 **/
261GLCoverageGLGetTexParameterReportsCorrectDefaultValuesForMultisampleTextureTargets::
262	GLCoverageGLGetTexParameterReportsCorrectDefaultValuesForMultisampleTextureTargets(Context& context)
263	: TestCase(context, "get_tex_parameter_reports_correct_default_values_for_multisample_texture_targets",
264			   "glGetTexParameter*() report correct default values for multisample texture targets.")
265	, gl_oes_texture_storage_multisample_2d_array_supported(GL_FALSE)
266	, to_id_2d(0)
267	, to_id_2d_array(0)
268{
269	/* Left blank on purpose */
270}
271
272/* Deinitializes test-specific ES objects */
273void GLCoverageGLGetTexParameterReportsCorrectDefaultValuesForMultisampleTextureTargets::deinit()
274{
275	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
276
277	if (to_id_2d != 0)
278	{
279		gl.deleteTextures(1, &to_id_2d);
280
281		to_id_2d = 0;
282	}
283
284	if (to_id_2d_array != 0)
285	{
286		gl.deleteTextures(1, &to_id_2d_array);
287
288		to_id_2d_array = 0;
289	}
290
291	/* Call base test class' deinit() */
292	TestCase::deinit();
293}
294
295/** Executes test iteration.
296 *
297 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
298 */
299tcu::TestNode::IterateResult GLCoverageGLGetTexParameterReportsCorrectDefaultValuesForMultisampleTextureTargets::
300	iterate()
301{
302	gl_oes_texture_storage_multisample_2d_array_supported =
303		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
304
305	const float			  epsilon = (float)1e-5;
306	const glw::Functions& gl	  = m_context.getRenderContext().getFunctions();
307
308	/* Generate texture objects */
309	gl.genTextures(1, &to_id_2d);
310
311	if (gl_oes_texture_storage_multisample_2d_array_supported)
312	{
313		gl.genTextures(1, &to_id_2d_array);
314	}
315
316	GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glGenTextures() call failed");
317
318	/* Bind the texture objects to multisample texture targets */
319	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d);
320
321	if (gl_oes_texture_storage_multisample_2d_array_supported)
322	{
323		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_2d_array);
324	}
325
326	GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glBindTexture() call failed");
327
328	/* Initialize texture storage */
329	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, /* samples */
330							   GL_RGBA8, 4,					 /* width */
331							   4,							 /* height */
332							   GL_TRUE);					 /* fixedsamplelocations */
333
334	if (gl_oes_texture_storage_multisample_2d_array_supported)
335	{
336		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2, /* samples */
337								   GL_RGBA8, 4,							   /* width */
338								   4,									   /* height */
339								   4,									   /* depth */
340								   GL_TRUE);							   /* fixedsamplelocations */
341	}
342
343	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture storage initialization failed");
344
345	/* List of supported texture targets when the extension is not present. */
346	glw::GLenum texture_targets_without_extension[] = { GL_TEXTURE_2D_MULTISAMPLE };
347
348	/* List of supported texture targets when the extension is present. */
349	glw::GLenum texture_targets_with_extension[] = { GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES };
350
351	/* Iterate through all the texture targets supported for the specific case. */
352	glw::GLenum* texture_targets = NULL;
353
354	unsigned int n_texture_targets = 0;
355
356	if (gl_oes_texture_storage_multisample_2d_array_supported)
357	{
358		n_texture_targets = sizeof(texture_targets_with_extension) / sizeof(texture_targets_with_extension[0]);
359		texture_targets   = texture_targets_with_extension;
360	}
361	else
362	{
363		n_texture_targets = sizeof(texture_targets_without_extension) / sizeof(texture_targets_without_extension[0]);
364		texture_targets   = texture_targets_without_extension;
365	}
366
367	for (unsigned int n_texture_target = 0; n_texture_target < n_texture_targets; ++n_texture_target)
368	{
369		glw::GLenum target = texture_targets[n_texture_target];
370
371		/* Iterate through all texture parameters */
372		const glw::GLenum texture_parameters[] = {
373			GL_TEXTURE_BASE_LEVEL, GL_TEXTURE_IMMUTABLE_FORMAT, GL_TEXTURE_MAX_LEVEL, GL_TEXTURE_SWIZZLE_R,
374			GL_TEXTURE_SWIZZLE_G,  GL_TEXTURE_SWIZZLE_B,		GL_TEXTURE_SWIZZLE_A,
375
376			/* The following are sampler states, hence are left out */
377
378			// GL_TEXTURE_COMPARE_FUNC,
379			// GL_TEXTURE_COMPARE_MODE,
380			// GL_TEXTURE_MAG_FILTER,
381			// GL_TEXTURE_MAX_LOD,
382			// GL_TEXTURE_MIN_FILTER,
383			// GL_TEXTURE_MIN_LOD,
384			// GL_TEXTURE_WRAP_S,
385			// GL_TEXTURE_WRAP_T,
386			// GL_TEXTURE_WRAP_R
387		};
388		const unsigned int n_texture_parameters = sizeof(texture_parameters) / sizeof(texture_parameters[0]);
389
390		for (unsigned int n_texture_parameter = 0; n_texture_parameter < n_texture_parameters; ++n_texture_parameter)
391		{
392			glw::GLenum texture_parameter = texture_parameters[n_texture_parameter];
393
394			/* Query implementation for the parameter values for texture target considered */
395			glw::GLint   expected_int_value = 0;
396			glw::GLfloat float_value		= 0.0f;
397			glw::GLint   int_value			= 0;
398
399			gl.getTexParameterfv(target, texture_parameter, &float_value);
400			gl.getTexParameteriv(target, texture_parameter, &int_value);
401
402			GLU_EXPECT_NO_ERROR(gl.getError(), "Either of the glGetTexParameter*() calls generated an error");
403
404			/* Verify the value is valid */
405			switch (texture_parameter)
406			{
407			case GL_TEXTURE_BASE_LEVEL:
408				expected_int_value = 0;
409				break;
410			case GL_TEXTURE_COMPARE_FUNC:
411				expected_int_value = GL_LEQUAL;
412				break;
413			case GL_TEXTURE_COMPARE_MODE:
414				expected_int_value = GL_NONE;
415				break;
416			case GL_TEXTURE_IMMUTABLE_FORMAT:
417				expected_int_value = GL_TRUE;
418				break;
419			case GL_TEXTURE_MAG_FILTER:
420				expected_int_value = GL_LINEAR;
421				break;
422			case GL_TEXTURE_MAX_LEVEL:
423				expected_int_value = 1000;
424				break;
425			case GL_TEXTURE_MAX_LOD:
426				expected_int_value = 1000;
427				break;
428			case GL_TEXTURE_MIN_FILTER:
429				expected_int_value = GL_NEAREST_MIPMAP_LINEAR;
430				break;
431			case GL_TEXTURE_MIN_LOD:
432				expected_int_value = -1000;
433				break;
434			case GL_TEXTURE_SWIZZLE_R:
435				expected_int_value = GL_RED;
436				break;
437			case GL_TEXTURE_SWIZZLE_G:
438				expected_int_value = GL_GREEN;
439				break;
440			case GL_TEXTURE_SWIZZLE_B:
441				expected_int_value = GL_BLUE;
442				break;
443			case GL_TEXTURE_SWIZZLE_A:
444				expected_int_value = GL_ALPHA;
445				break;
446			case GL_TEXTURE_WRAP_S:
447				expected_int_value = GL_REPEAT;
448				break;
449			case GL_TEXTURE_WRAP_T:
450				expected_int_value = GL_REPEAT;
451				break;
452			case GL_TEXTURE_WRAP_R:
453				expected_int_value = GL_REPEAT;
454				break;
455
456			default:
457			{
458				TCU_FAIL("Unrecognized texture parameter name");
459			}
460			} /* switch (texture_parameter) */
461
462			/* Verify integer value the implementation returned */
463			if (expected_int_value != int_value)
464			{
465				m_testCtx.getLog() << tcu::TestLog::Message << "Implementation returned an invalid integer value of "
466								   << int_value << " instead of the expected value " << expected_int_value
467								   << " for property " << texture_parameter << " of texture target " << target
468								   << tcu::TestLog::EndMessage;
469
470				TCU_FAIL("Invalid integer value returned by glGetTexParameteriv()");
471			}
472
473			/* Verify floating-point value the implementation returned */
474			if (de::abs(float(expected_int_value) - float_value) > epsilon)
475			{
476				m_testCtx.getLog() << tcu::TestLog::Message
477								   << "Implementation returned an invalid floating-point value of " << float_value
478								   << " instead of the expected value " << expected_int_value << " for property "
479								   << texture_parameter << " of texture target " << target << tcu::TestLog::EndMessage;
480
481				TCU_FAIL("Invalid floating-point value returned by glGetTexParameteriv()");
482			}
483		} /* for (all texture parameters) */
484	}	 /* for (all texture targets) */
485
486	/* All done */
487	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
488	return STOP;
489}
490
491/** Constructor.
492 *
493 *  @param context Rendering context handle.
494 **/
495GLCoverageGLSampleMaskModeStatusIsReportedCorrectlyTest::GLCoverageGLSampleMaskModeStatusIsReportedCorrectlyTest(
496	Context& context)
497	: TestCase(context, "gl_sample_mask_mode_status_is_reported_correctly",
498			   "glGet*() calls report correct disabled/enabled status of GL_SAMPLE_MASK mode.")
499{
500	/* Left blank on purpose */
501}
502
503/** Executes test iteration.
504 *
505 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
506 */
507tcu::TestNode::IterateResult GLCoverageGLSampleMaskModeStatusIsReportedCorrectlyTest::iterate()
508{
509	const float			  epsilon = (float)1e-5;
510	const glw::Functions& gl	  = m_context.getRenderContext().getFunctions();
511
512	/* Check GL_SAMPLE_MASK is disabled by default */
513	glw::GLint enabled = gl.isEnabled(GL_SAMPLE_MASK);
514	GLU_EXPECT_NO_ERROR(gl.getError(), "Unexpected error generated by glIsEnabled(GL_SAMPLE_MASK) call.");
515
516	if (enabled != GL_FALSE)
517	{
518		TCU_FAIL("GL_SAMPLE_MASK mode is considered enabled by default which is incorrect.");
519	}
520
521	/* Verify glGet*() calls also report the mode to be disabled */
522	glw::GLboolean bool_value  = GL_TRUE;
523	glw::GLfloat   float_value = 1.0f;
524	glw::GLint	 int_value   = 1;
525
526	gl.getBooleanv(GL_SAMPLE_MASK, &bool_value);
527	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv() reported an error when queried for GL_SAMPLE_MASK property");
528
529	if (bool_value != GL_FALSE)
530	{
531		TCU_FAIL("Invalid boolean value reported for GL_SAMPLE_MASK property");
532	}
533
534	gl.getFloatv(GL_SAMPLE_MASK, &float_value);
535	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() reported an error when queried for GL_SAMPLE_MASK property");
536
537	if (de::abs(float_value - float(GL_FALSE)) > epsilon)
538	{
539		TCU_FAIL("Invalid float value reported for GL_SAMPLE_MASK property");
540	}
541
542	gl.getIntegerv(GL_SAMPLE_MASK, &int_value);
543	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() reported an error when queried for GL_SAMPLE_MASK property");
544
545	if (int_value != GL_FALSE)
546	{
547		TCU_FAIL("Invalid integer value reported for GL_SAMPLE_MASK property");
548	}
549
550	/* Enable GL_SAMPLE_MASK mode */
551	gl.enable(GL_SAMPLE_MASK);
552
553	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_SAMPLE_MASK) call generated an unexpected error");
554
555	/* Verify values reported by glIsEnabled(), as well as GL getters is still correct */
556	enabled = gl.isEnabled(GL_SAMPLE_MASK);
557	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsEnabled(GL_SAMPLE_MASK) call generated an unexpected error");
558
559	if (enabled != GL_TRUE)
560	{
561		TCU_FAIL(
562			"glIsEnabled(GL_SAMPLE_MASK) did not report GL_TRUE after a successful glEnable(GL_SAMPLE_MASK) call.");
563	}
564
565	gl.getBooleanv(GL_SAMPLE_MASK, &bool_value);
566	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv() reported an error when queried for GL_SAMPLE_MASK property");
567
568	if (bool_value != GL_TRUE)
569	{
570		TCU_FAIL("Invalid boolean value reported for GL_SAMPLE_MASK property");
571	}
572
573	gl.getFloatv(GL_SAMPLE_MASK, &float_value);
574	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() reported an error when queried for GL_SAMPLE_MASK property");
575
576	if (de::abs(float_value - float(GL_TRUE)) > epsilon)
577	{
578		TCU_FAIL("Invalid float value reported for GL_SAMPLE_MASK property");
579	}
580
581	gl.getIntegerv(GL_SAMPLE_MASK, &int_value);
582	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() reported an error when queried for GL_SAMPLE_MASK property");
583
584	if (int_value != GL_TRUE)
585	{
586		TCU_FAIL("Invalid integer value reported for GL_SAMPLE_MASK property");
587	}
588
589	/* Disable the mode and see if the getters react accordingly */
590	gl.disable(GL_SAMPLE_MASK);
591	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable(GL_SAMPLE_MASK) call generated an unexpected error");
592
593	enabled = gl.isEnabled(GL_SAMPLE_MASK);
594	GLU_EXPECT_NO_ERROR(gl.getError(), "glIsEnabled(GL_SAMPLE_MASK) call generated an unexpected error");
595
596	if (enabled != GL_FALSE)
597	{
598		TCU_FAIL(
599			"glIsEnabled(GL_SAMPLE_MASK) did not report GL_FALSE after a successful glDisable(GL_SAMPLE_MASK) call.");
600	}
601
602	gl.getBooleanv(GL_SAMPLE_MASK, &bool_value);
603	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv() reported an error when queried for GL_SAMPLE_MASK property");
604
605	if (bool_value != GL_FALSE)
606	{
607		TCU_FAIL("Invalid boolean value reported for GL_SAMPLE_MASK property");
608	}
609
610	gl.getFloatv(GL_SAMPLE_MASK, &float_value);
611	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFloatv() reported an error when queried for GL_SAMPLE_MASK property");
612
613	if (de::abs(float_value - float(GL_FALSE)) > epsilon)
614	{
615		TCU_FAIL("Invalid float value reported for GL_SAMPLE_MASK property");
616	}
617
618	gl.getIntegerv(GL_SAMPLE_MASK, &int_value);
619	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() reported an error when queried for GL_SAMPLE_MASK property");
620
621	if (int_value != GL_FALSE)
622	{
623		TCU_FAIL("Invalid integer value reported for GL_SAMPLE_MASK property");
624	}
625
626	/* All good! */
627	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
628	return STOP;
629}
630
631/** Constructor.
632 *
633 *  @param context Rendering context handle.
634 **/
635GLCoverageGLTexParameterHandlersAcceptZeroBaseLevelForExtensionSpecificTextureTargetsTest::
636	GLCoverageGLTexParameterHandlersAcceptZeroBaseLevelForExtensionSpecificTextureTargetsTest(Context& context)
637	: TestCase(context, "gl_tex_parameter_handlers_accept_zero_base_level",
638			   "glTexParameter*() calls should not generate an error if zero base "
639			   "level is requested for 2D multisample or 2D multisample array texture targets.")
640	, are_2d_array_multisample_tos_supported(false)
641	, to_id_2d(0)
642	, to_id_2d_array(0)
643{
644	/* Left blank on purpose */
645}
646
647/* Deinitializes texture objects created specifically for this test case. */
648void GLCoverageGLTexParameterHandlersAcceptZeroBaseLevelForExtensionSpecificTextureTargetsTest::deinit()
649{
650	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
651
652	if (to_id_2d != 0)
653	{
654		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
655		gl.deleteTextures(1, &to_id_2d);
656	}
657
658	if (to_id_2d_array != 0)
659	{
660		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 0);
661		gl.deleteTextures(1, &to_id_2d_array);
662	}
663
664	/* Call base class' deinit() */
665	TestCase::deinit();
666}
667
668/* Initializes test instance: creates test-specific texture objects. */
669void GLCoverageGLTexParameterHandlersAcceptZeroBaseLevelForExtensionSpecificTextureTargetsTest::initInternals()
670{
671	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
672
673	/* Generate texture objects */
674	gl.genTextures(1, &to_id_2d);
675
676	if (are_2d_array_multisample_tos_supported)
677	{
678		gl.genTextures(1, &to_id_2d_array);
679	}
680
681	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not generate texture object(s)");
682
683	/* Bind the texture objects to extension-specific texture targets */
684	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_2d);
685
686	if (are_2d_array_multisample_tos_supported)
687	{
688		gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, to_id_2d_array);
689	}
690
691	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind texture object(s) to corresponding texture target(s).");
692}
693
694/** Executes test iteration.
695 *
696 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
697 */
698tcu::TestNode::IterateResult GLCoverageGLTexParameterHandlersAcceptZeroBaseLevelForExtensionSpecificTextureTargetsTest::
699	iterate()
700{
701	are_2d_array_multisample_tos_supported =
702		m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
703
704	initInternals();
705
706	/* Initialize texture storage for 2D multisample texture object */
707	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
708
709	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2 /* samples */, GL_RGBA8, 4, /* width */
710							   4,														/* height */
711							   GL_TRUE /* fixedsamplelocations */);
712
713	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up an immutable 2D multisample texture object");
714
715	/* Initialize texture storage for 2D multisample array texture object */
716	if (are_2d_array_multisample_tos_supported)
717	{
718		gl.texStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, 2 /* samples */, GL_RGBA8, 4 /* width */,
719								   4 /* height */, 4 /* depth */, GL_TRUE /* fixedsamplelocations */);
720
721		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up an immutable 2D multisample array texture object");
722	}
723
724	/* Force a zero base level setting for 2D multisample texture using all available glTexParameter*() entry-points */
725	glw::GLfloat zero_float = 0.0f;
726	glw::GLint   zero_int   = 0;
727
728	gl.texParameterf(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL, 0.0f);
729	gl.texParameterfv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL, &zero_float);
730	gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL, 0);
731	gl.texParameteriv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL, &zero_int);
732
733	GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glTexParameter*() call reported an error.");
734
735	/* Do the same for 2D multisample array texture */
736	if (are_2d_array_multisample_tos_supported)
737	{
738		gl.texParameterf(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, 0.0f);
739		gl.texParameterfv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, &zero_float);
740		gl.texParameteri(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, 0);
741		gl.texParameteriv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES, GL_TEXTURE_BASE_LEVEL, &zero_int);
742
743		GLU_EXPECT_NO_ERROR(gl.getError(), "At least one glTexParameter*() call reported an error.");
744	}
745
746	/* All good! */
747	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
748	return STOP;
749}
750} /* glcts namespace */
751