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  es31cTextureStorageMultisampleGetMultisamplefvTests.cpp
27 * \brief Implements conformance tests testing whether glGetMultisamplefv()
28 *        works correctly. (ES3.1 only)
29 */ /*-------------------------------------------------------------------*/
30
31#include "es31cTextureStorageMultisampleGetMultisamplefvTests.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 <string>
40#include <vector>
41
42namespace glcts
43{
44/** Constructor.
45 *
46 *  @param context Rendering context handle.
47 **/
48MultisampleTextureGetMultisamplefvIndexEqualGLSamplesRejectedTest::
49	MultisampleTextureGetMultisamplefvIndexEqualGLSamplesRejectedTest(Context& context)
50	: TestCase(context, "multisample_texture_get_multisamplefv_index_equal_gl_samples_rejected",
51			   "Verifies GetMultisamplefv() rejects index equal to GL_SAMPLES value")
52{
53	/* Left blank on purpose */
54}
55
56/** Executes test iteration.
57 *
58 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
59 */
60tcu::TestNode::IterateResult MultisampleTextureGetMultisamplefvIndexEqualGLSamplesRejectedTest::iterate()
61{
62	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
63	glw::GLint			  gl_samples_value = 0;
64
65	/* Get GL_SAMPLES value */
66	gl.getIntegerv(GL_SAMPLES, &gl_samples_value);
67
68	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_SAMPLES value");
69
70	/* Issue call with valid parameters, but invalid index equal to GL_SAMPLES value */
71	glw::GLfloat val[2];
72	gl.getMultisamplefv(GL_SAMPLE_POSITION, gl_samples_value, val);
73
74	/* Check if the expected error code was reported */
75	if (gl.getError() != GL_INVALID_VALUE)
76	{
77		TCU_FAIL("Invalid error code reported");
78	}
79
80	/* Test case passed */
81	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
82
83	return STOP;
84}
85
86/** Constructor.
87 *
88 *  @param context Rendering context handle.
89 **/
90MultisampleTextureGetMultisamplefvIndexGreaterGLSamplesRejectedTest::
91	MultisampleTextureGetMultisamplefvIndexGreaterGLSamplesRejectedTest(Context& context)
92	: TestCase(context, "multisample_texture_get_multisamplefv_index_greater_gl_samples_rejected",
93			   "Verifies GetMultisamplefv() rejects index greater than GL_SAMPLES value")
94{
95	/* Left blank on purpose */
96}
97
98/** Executes test iteration.
99 *
100 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
101 */
102tcu::TestNode::IterateResult MultisampleTextureGetMultisamplefvIndexGreaterGLSamplesRejectedTest::iterate()
103{
104	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
105	glw::GLint			  gl_samples_value = 0;
106
107	/* Get GL_SAMPLES value */
108	gl.getIntegerv(GL_SAMPLES, &gl_samples_value);
109
110	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_SAMPLES value");
111
112	/* Issue call with valid parameters, but invalid index greater than GL_SAMPLES value */
113	glw::GLfloat val[2];
114	gl.getMultisamplefv(GL_SAMPLE_POSITION, gl_samples_value + 1, val);
115
116	/* Check if the expected error code was reported */
117	if (gl.getError() != GL_INVALID_VALUE)
118	{
119		TCU_FAIL("Invalid error code reported");
120	}
121
122	/* Test case passed */
123	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
124
125	return STOP;
126}
127
128/** Constructor.
129 *
130 *  @param context Rendering context handle.
131 **/
132MultisampleTextureGetMultisamplefvInvalidPnameRejectedTest::MultisampleTextureGetMultisamplefvInvalidPnameRejectedTest(
133	Context& context)
134	: TestCase(context, "multisample_texture_get_multisamplefv_invalid_pname_rejected",
135			   "Verifies GetMultisamplefv() rejects invalid pname")
136{
137	/* Left blank on purpose */
138}
139
140/** Executes test iteration.
141 *
142 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
143 */
144tcu::TestNode::IterateResult MultisampleTextureGetMultisamplefvInvalidPnameRejectedTest::iterate()
145{
146	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
147
148	/* Issue call with valid parameters, but invalid pname GL_SAMPLES */
149	glw::GLfloat val[2];
150	gl.getMultisamplefv(GL_SAMPLES, 0, val);
151
152	/* Check if the expected error code was reported */
153	glw::GLenum error_code = gl.getError();
154
155	if (error_code != GL_INVALID_ENUM)
156	{
157		TCU_FAIL("Invalid error code reported");
158	}
159
160	/* Test case passed */
161	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
162
163	return STOP;
164}
165
166/** Constructor.
167 *
168 *  @param context Rendering context handle.
169 **/
170MultisampleTextureGetMultisamplefvNullValArgumentsAcceptedTest::
171	MultisampleTextureGetMultisamplefvNullValArgumentsAcceptedTest(Context& context)
172	: TestCase(context, "multisample_texture_get_multisamplefv_null_val_arguments_accepted",
173			   "Verifies NULL val arguments accepted for valid glGetMultisamplefv() calls.")
174	, fbo_id(0)
175	, to_2d_multisample_id(0)
176{
177	/* Left blank on purpose */
178}
179
180/** Executes test iteration.
181 *
182 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
183 */
184tcu::TestNode::IterateResult MultisampleTextureGetMultisamplefvNullValArgumentsAcceptedTest::iterate()
185{
186	/* Issue call with valid parameters, but invalid pname GL_SAMPLES */
187	glw::GLenum			  error_code = GL_NO_ERROR;
188	const glw::Functions& gl		 = m_context.getRenderContext().getFunctions();
189
190	/* gl.getMultisamplefv(GL_SAMPLES, 0, NULL) is not legal, removed */
191
192	/* Create multisampled FBO, as default framebuffer is not multisampled */
193
194	gl.genTextures(1, &to_2d_multisample_id);
195
196	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed");
197
198	if (to_2d_multisample_id == 0)
199	{
200		TCU_FAIL("Texture object has not been generated properly");
201	}
202
203	glw::GLint samples = 0;
204
205	gl.getInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, /* target */
206						   GL_RGBA8, GL_SAMPLES, 1,   /* bufSize */
207						   &samples);
208
209	GLU_EXPECT_NO_ERROR(gl.getError(), "getInternalformativ() call failed");
210
211	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_2d_multisample_id);
212
213	/* Configure the texture object storage */
214	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples, GL_RGBA8, 1, /* width */
215							   1,												/* height */
216							   GL_TRUE);										/* fixedsamplelocations */
217
218	GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2DMultisample() call failed");
219
220	gl.genFramebuffers(1, &fbo_id);
221
222	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed");
223
224	if (fbo_id == 0)
225	{
226		TCU_FAIL("Framebuffer object has not been generated properly");
227	}
228
229	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
230
231	gl.framebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, to_2d_multisample_id,
232							0);
233
234	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set up framebuffer's attachments");
235
236	glw::GLenum fbo_completeness_status = 0;
237
238	fbo_completeness_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
239
240	if (fbo_completeness_status != GL_FRAMEBUFFER_COMPLETE)
241	{
242		m_testCtx.getLog() << tcu::TestLog::Message << "Source FBO completeness status is: " << fbo_completeness_status
243						   << ", expected: GL_FRAMEBUFFER_COMPLETE" << tcu::TestLog::EndMessage;
244
245		TCU_FAIL("Source FBO is considered incomplete which is invalid");
246	}
247
248	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
249
250	/* Get GL_SAMPLES value */
251	glw::GLint gl_samples_value = 0;
252
253	gl.getIntegerv(GL_SAMPLES, &gl_samples_value);
254
255	error_code = gl.getError();
256	GLU_EXPECT_NO_ERROR(error_code, "Failed to retrieve GL_SAMPLES value");
257
258	glw::GLfloat val[2];
259	gl.getMultisamplefv(GL_SAMPLE_POSITION, 0, val);
260
261	error_code = gl.getError();
262
263	GLU_EXPECT_NO_ERROR(error_code, "glGetMultisamplefv() call failed");
264
265	/* Iterate through valid index values */
266	for (glw::GLint index = 0; index < gl_samples_value; ++index)
267	{
268		/* Execute the test */
269		gl.getMultisamplefv(GL_SAMPLE_POSITION, index, val);
270
271		error_code = gl.getError();
272		GLU_EXPECT_NO_ERROR(error_code, "A valid glGetMultisamplefv() call reported an error");
273	} /* for (all valid index argument values) */
274
275	/* Test case passed */
276	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
277
278	return STOP;
279}
280
281/** Deinitializes ES objects created during test execution */
282void MultisampleTextureGetMultisamplefvNullValArgumentsAcceptedTest::deinit()
283{
284	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
285
286	/* Unbind framebuffer object bound to GL_DRAW_FRAMEBUFFER target */
287	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
288
289	/* Unbind texture object bound to GL_TEXTURE_2D_MULTISAMPLE texture target */
290	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
291
292	/* Delete a 2D multisample texture object of id to_2d_multisample_id */
293	if (to_2d_multisample_id != 0)
294	{
295		gl.deleteTextures(1, &to_2d_multisample_id);
296
297		to_2d_multisample_id = 0;
298	}
299
300	/* Delete a framebuffer object of id fbo_id */
301	if (fbo_id != 0)
302	{
303		gl.deleteFramebuffers(1, &fbo_id);
304
305		fbo_id = 0;
306	}
307}
308
309/** Constructor.
310 *
311 *  @param context Rendering context handle.
312 **/
313MultisampleTextureGetMultisamplefvSamplePositionValuesValidationTest::
314	MultisampleTextureGetMultisamplefvSamplePositionValuesValidationTest(Context& context)
315	: TestCase(context, "multisample_texture_get_multisamplefv_sample_position_values_validation",
316			   "Verifies spec-wise correct values are reported for valid calls with GL_SAMPLE_POSITION pname")
317{
318	/* Left blank on purpose */
319}
320
321/** Executes test iteration.
322 *
323 *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
324 */
325tcu::TestNode::IterateResult MultisampleTextureGetMultisamplefvSamplePositionValuesValidationTest::iterate()
326{
327	/* Get GL_SAMPLES value */
328	const glw::Functions& gl			   = m_context.getRenderContext().getFunctions();
329	glw::GLint			  gl_samples_value = 0;
330
331	gl.getIntegerv(GL_SAMPLES, &gl_samples_value);
332	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to retrieve GL_SAMPLES value");
333
334	/* Iterate through valid index values */
335	for (glw::GLint index = 0; index < gl_samples_value; ++index)
336	{
337		/* Execute the test */
338		glw::GLfloat val[2] = { -1.0f, -1.0f };
339
340		gl.getMultisamplefv(GL_SAMPLE_POSITION, index, val);
341		GLU_EXPECT_NO_ERROR(gl.getError(), "A valid glGetMultisamplefv() call reported an error");
342
343		if (val[0] < 0.0f || val[0] > 1.0f || val[1] < 0.0f || val[1] > 1.0f)
344		{
345			m_testCtx.getLog() << tcu::TestLog::Message << "One or more coordinates used to describe sample position: "
346							   << "(" << val[0] << ", " << val[1] << ") is outside the valid <0, 1> range."
347							   << tcu::TestLog::EndMessage;
348
349			TCU_FAIL("Invalid sample position reported");
350		}
351	} /* for (all valid index argument values) */
352
353	/* Test case passed */
354	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
355
356	return STOP;
357}
358} /* glcts namespace */
359