• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2015-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 #include "esextcGeometryShaderLayeredFBO.hpp"
24 
25 #include "gluDefs.hpp"
26 #include "glwEnums.hpp"
27 #include "glwFunctions.hpp"
28 #include "tcuTestLog.hpp"
29 #include <cstring>
30 
31 namespace glcts
32 {
33 
34 const unsigned int GeometryShaderLayeredFBOShared::n_shared_fbo_ids = 4; /* as per test spec */
35 const unsigned int GeometryShaderLayeredFBOShared::n_shared_to_ids  = 7; /* as per test spec */
36 const glw::GLuint  GeometryShaderLayeredFBOShared::shared_to_depth  = 4; /* as per test spec */
37 const glw::GLuint  GeometryShaderLayeredFBOShared::shared_to_height = 4; /* as per test spec */
38 const glw::GLuint  GeometryShaderLayeredFBOShared::shared_to_width  = 4; /* as per test spec */
39 
40 /** Checks if the bound draw framebuffer's completeness status is equal to the value
41  *  specified by the caller.
42  *
43  *  @param test_context                 Test context used by the conformance test.
44  *  @param gl                           ES / GL entry-points.
45  *  @param fbo_id                       ID of the framebuffer to use for the query.
46  *  @param expected_completeness_status Expected completeness status (described by a GLenum value)
47  *
48  *  @return true if the draw framebuffer's completeness status matches the expected value,
49  *          false otherwise
50  */
checkFBOCompleteness(tcu::TestContext & test_context,const glw::Functions & gl,glw::GLenum fbo_id,glw::GLenum expected_completeness_status)51 bool GeometryShaderLayeredFBOShared::checkFBOCompleteness(tcu::TestContext& test_context, const glw::Functions& gl,
52 														  glw::GLenum fbo_id, glw::GLenum expected_completeness_status)
53 {
54 	glw::GLenum current_fbo_status = GL_NONE;
55 	bool		result			   = true;
56 
57 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id);
58 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
59 
60 	current_fbo_status = gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
61 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCheckFramebufferStatus() call failed.");
62 
63 	if (current_fbo_status != expected_completeness_status)
64 	{
65 		/* Please check doxygen documentation of GeometryShaderIncompleteLayeredFBOTest class
66 		 * for more details, if you ever reach this location */
67 		test_context.getLog() << tcu::TestLog::Message << "Test iteration [" << fbo_id << "] failed. "
68 																						  "Expected: ["
69 							  << expected_completeness_status << "], "
70 																 "got: ["
71 							  << current_fbo_status << "]" << tcu::TestLog::EndMessage;
72 
73 		result = false;
74 	}
75 
76 	return result;
77 }
78 
79 /** Deinitializes framebuffer objects, whose IDs are passed by the caller.
80  *
81  *  @param gl      ES / GL entry-points
82  *  @param fbo_ids Exactly GeometryShaderLayeredFBOShared::n_shared_fbo_ids FBO
83  *                 ids to be deinitialized.
84  */
deinitFBOs(const glw::Functions & gl,const glw::GLuint * fbo_ids)85 void GeometryShaderLayeredFBOShared::deinitFBOs(const glw::Functions& gl, const glw::GLuint* fbo_ids)
86 {
87 	if (fbo_ids != DE_NULL)
88 	{
89 		gl.deleteFramebuffers(GeometryShaderLayeredFBOShared::n_shared_fbo_ids, fbo_ids);
90 	}
91 }
92 
93 /** Deinitializes texture obejcts, whose IDs are passed by the caller.
94  *
95  *  @param gl     ES / GL entry-points
96  *  @param to_ids Exactly GeometryShaderLayeredFBOShared::n_shared_to_ids Texture
97  *                Object IDs to be deinitialized.
98  */
deinitTOs(const glw::Functions & gl,const glw::GLuint * to_ids)99 void GeometryShaderLayeredFBOShared::deinitTOs(const glw::Functions& gl, const glw::GLuint* to_ids)
100 {
101 	if (to_ids != DE_NULL)
102 	{
103 		gl.deleteTextures(GeometryShaderLayeredFBOShared::n_shared_to_ids, to_ids);
104 	}
105 }
106 
107 /** Initializes all framebuffer objects required to run layered framebufer object conformance test.
108  *
109  *  @param gl                    ES / GL entry-points
110  *  @param pGLFramebufferTexture glFramebufferTexture{EXT}() entry-point func ptr.
111  *  @param to_ids                Exactly 7 Texture Object IDs, initialized as per test spec.
112  *  @param out_fbo_ids           Deref will be used to store 4 FBO ids, initialized as per test spec.
113  **/
initFBOs(const glw::Functions & gl,glw::glFramebufferTextureFunc pGLFramebufferTexture,const glw::GLuint * to_ids,glw::GLuint * out_fbo_ids)114 void GeometryShaderLayeredFBOShared::initFBOs(const glw::Functions&			gl,
115 											  glw::glFramebufferTextureFunc pGLFramebufferTexture,
116 											  const glw::GLuint* to_ids, glw::GLuint* out_fbo_ids)
117 {
118 	const glw::GLuint to_id_a	  = to_ids[0];
119 	const glw::GLuint to_id_a_prim = to_ids[1];
120 	const glw::GLuint to_id_b	  = to_ids[2];
121 	const glw::GLuint to_id_c	  = to_ids[3];
122 	const glw::GLuint to_id_d	  = to_ids[4];
123 	const glw::GLuint to_id_e	  = to_ids[5];
124 	const glw::GLuint to_id_f	  = to_ids[6];
125 
126 	gl.genFramebuffers(n_shared_fbo_ids, out_fbo_ids);
127 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
128 
129 	/* Set up framebuffer object A */
130 	const glw::GLenum  fbo_a_draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_NONE, GL_COLOR_ATTACHMENT2 };
131 	const glw::GLenum  fbo_b_draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
132 	const glw::GLenum  fbo_c_draw_buffers[] = { GL_COLOR_ATTACHMENT0 };
133 	const glw::GLenum  fbo_d_draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
134 	const glw::GLuint  fbo_id_a				= out_fbo_ids[0];
135 	const glw::GLuint  fbo_id_b				= out_fbo_ids[1];
136 	const glw::GLuint  fbo_id_c				= out_fbo_ids[2];
137 	const glw::GLuint  fbo_id_d				= out_fbo_ids[3];
138 	const unsigned int n_fbo_a_draw_buffers = sizeof(fbo_a_draw_buffers) / sizeof(fbo_a_draw_buffers[0]);
139 	const unsigned int n_fbo_b_draw_buffers = sizeof(fbo_b_draw_buffers) / sizeof(fbo_b_draw_buffers[0]);
140 	const unsigned int n_fbo_c_draw_buffers = sizeof(fbo_c_draw_buffers) / sizeof(fbo_c_draw_buffers[0]);
141 	const unsigned int n_fbo_d_draw_buffers = sizeof(fbo_d_draw_buffers) / sizeof(fbo_d_draw_buffers[0]);
142 
143 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id_a);
144 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
145 
146 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id_a, 0);	 /* level */
147 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, to_id_b, 0);	 /* level */
148 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, to_id_a_prim, 0); /* level */
149 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture() call(s) failed.");
150 
151 	gl.drawBuffers(n_fbo_a_draw_buffers, fbo_a_draw_buffers);
152 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffers() call failed.");
153 
154 	/* Set up framebuffer object B */
155 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id_b);
156 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
157 
158 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id_c, 0); /* level */
159 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_a, 0); /* level */
160 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture() call(s) failed.");
161 
162 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, to_id_d, 0); /* level */
163 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
164 
165 	gl.drawBuffers(n_fbo_b_draw_buffers, fbo_b_draw_buffers);
166 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffers() call failed.");
167 
168 	/* Set up framebuffer object C */
169 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id_c);
170 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
171 
172 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id_d, 0); /* level */
173 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTextureLayer() call failed.");
174 
175 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, to_id_a_prim, 0); /* level */
176 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture() call failed.");
177 
178 	gl.drawBuffers(n_fbo_c_draw_buffers, fbo_c_draw_buffers);
179 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBufers() call failed.");
180 
181 	/* Set up framebuffer object D */
182 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_id_d);
183 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
184 
185 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, to_id_e, 0); /* level */
186 	pGLFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, to_id_f, 0); /* level */
187 	GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture() call(s) failed.");
188 
189 	gl.drawBuffers(n_fbo_d_draw_buffers, fbo_d_draw_buffers);
190 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffers() call failed.");
191 }
192 
193 /** Initializes exactly seven texture objects, as per test spec.
194  *
195  *  @param gl                         ES / GL entry-points
196  *  @param pGLTexStorage3DMultisample glTexStorage3DMultisample{EXT}() entry-point func ptr.
197  *  @param out_to_ids                 Deref will be used to store 7 texture object IDs, initialized
198  *                                    as per test spec.
199  */
initTOs(const glw::Functions & gl,glw::glTexStorage3DMultisampleFunc pGLTexStorage3DMultisample,glw::GLuint * out_to_ids)200 void GeometryShaderLayeredFBOShared::initTOs(const glw::Functions&				gl,
201 											 glw::glTexStorage3DMultisampleFunc pGLTexStorage3DMultisample,
202 											 glw::GLuint*						out_to_ids)
203 {
204 	gl.genTextures(n_shared_to_ids, out_to_ids);
205 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
206 
207 	/* Set up texture object A */
208 	const glw::GLuint to_id_a	  = out_to_ids[0];
209 	const glw::GLuint to_id_a_prim = out_to_ids[1];
210 	const glw::GLuint to_id_b	  = out_to_ids[2];
211 	const glw::GLuint to_id_c	  = out_to_ids[3];
212 	const glw::GLuint to_id_d	  = out_to_ids[4];
213 	const glw::GLuint to_id_e	  = out_to_ids[5];
214 	const glw::GLuint to_id_f	  = out_to_ids[6];
215 
216 	gl.bindTexture(GL_TEXTURE_2D, to_id_a);
217 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
218 
219 	gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
220 					GL_RGBA8,		  /* color-renderable internalformat */
221 					shared_to_width, shared_to_height);
222 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
223 
224 	/* Set up texture object A' */
225 	gl.bindTexture(GL_TEXTURE_2D, to_id_a_prim);
226 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
227 
228 	gl.texStorage2D(GL_TEXTURE_2D, 1,	 /* levels */
229 					GL_DEPTH_COMPONENT16, /* depth-renderable internalformat */
230 					shared_to_width, shared_to_height);
231 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
232 
233 	/* Set up texture object B */
234 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, to_id_b);
235 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
236 
237 	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, /* levels */
238 					GL_RGBA8,				/* color-renderable internalformat */
239 					shared_to_width, shared_to_height, shared_to_depth);
240 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
241 
242 	/* Set up texture object C */
243 	gl.bindTexture(GL_TEXTURE_3D, to_id_c);
244 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
245 
246 	gl.texStorage3D(GL_TEXTURE_3D, 1, /* levels */
247 					GL_RGBA8,		  /* color-renderable internalformats */
248 					shared_to_width, shared_to_height, shared_to_depth);
249 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
250 
251 	/* Set up texture object D */
252 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, to_id_d);
253 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
254 
255 	gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, /* levels */
256 					GL_RGBA8,				/* color-renderable internalformat */
257 					shared_to_width, shared_to_height);
258 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
259 
260 	/* Set up texture object E */
261 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, to_id_e);
262 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
263 
264 	gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,				/* samples */
265 							   GL_RGBA8,									/* color-renderable internalformat */
266 							   shared_to_width, shared_to_height, GL_TRUE); /* fixedsamplelocations */
267 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2DMultisample() call failed.");
268 
269 	/* Set up texture object F */
270 	gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, to_id_f);
271 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
272 
273 	pGLTexStorage3DMultisample(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, 2, /* samples */
274 							   GL_RGBA8,						   /* color-renderable internalformat */
275 							   shared_to_width, shared_to_height, shared_to_depth, GL_TRUE); /* fixedsamplelocations */
276 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3DMultisample() call failed.");
277 }
278 
279 /** Constructor
280  *
281  * @param context       Test context
282  * @param extParams     Not used.
283  * @param name          Test case's name
284  * @param description   Test case's description
285  **/
GeometryShaderIncompleteLayeredFBOTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)286 GeometryShaderIncompleteLayeredFBOTest::GeometryShaderIncompleteLayeredFBOTest(Context&				context,
287 																			   const ExtParameters& extParams,
288 																			   const char*			name,
289 																			   const char*			description)
290 	: TestCaseBase(context, extParams, name, description), m_fbo_ids(DE_NULL), m_to_ids(DE_NULL)
291 {
292 	// left blank intentionally
293 }
294 
295 /** Deinitializes GLES objects created during the test. */
deinit()296 void GeometryShaderIncompleteLayeredFBOTest::deinit()
297 {
298 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
299 
300 	/* Release framebuffer objects */
301 	GeometryShaderLayeredFBOShared::deinitFBOs(gl, m_fbo_ids);
302 
303 	if (m_fbo_ids != DE_NULL)
304 	{
305 		delete[] m_fbo_ids;
306 
307 		m_fbo_ids = DE_NULL;
308 	}
309 
310 	/* Release texture objects */
311 	GeometryShaderLayeredFBOShared::deinitTOs(gl, m_to_ids);
312 
313 	if (m_to_ids != DE_NULL)
314 	{
315 		delete[] m_to_ids;
316 
317 		m_to_ids = DE_NULL;
318 	}
319 
320 	/* Release base class */
321 	TestCaseBase::deinit();
322 }
323 
324 /** Executes the test.
325  *
326  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
327  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
328  *  Note the function throws exception should an error occur!
329  **/
iterate()330 tcu::TestNode::IterateResult GeometryShaderIncompleteLayeredFBOTest::iterate()
331 {
332 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
333 	bool				  result = true;
334 
335 	/* This test should only run if EXT_geometry_shader is supported. */
336 	if (!m_is_geometry_shader_extension_supported)
337 	{
338 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
339 	}
340 
341 	/* Set up texture objects */
342 	m_to_ids = new glw::GLuint[GeometryShaderLayeredFBOShared::n_shared_to_ids];
343 
344 	GeometryShaderLayeredFBOShared::initTOs(gl, gl.texStorage3DMultisample, m_to_ids);
345 
346 	/* Set up framebuffer objects */
347 	m_fbo_ids = new glw::GLuint[GeometryShaderLayeredFBOShared::n_shared_fbo_ids];
348 
349 	GeometryShaderLayeredFBOShared::initFBOs(gl, gl.framebufferTexture, m_to_ids, m_fbo_ids);
350 
351 	/* Verify framebuffer completeness */
352 	const glw::GLuint  incomplete_fbo_ids[] = { m_fbo_ids[0], m_fbo_ids[1], m_fbo_ids[2], m_fbo_ids[3] };
353 	const unsigned int n_incomplete_fbo_ids = sizeof(incomplete_fbo_ids) / sizeof(incomplete_fbo_ids[0]);
354 
355 	for (unsigned int n_incomplete_fbo_id = 0; n_incomplete_fbo_id < n_incomplete_fbo_ids; ++n_incomplete_fbo_id)
356 	{
357 		result &= GeometryShaderLayeredFBOShared::checkFBOCompleteness(
358 			m_testCtx, gl, incomplete_fbo_ids[n_incomplete_fbo_id], m_glExtTokens.FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS);
359 	} /* for (all FBO ids) */
360 
361 	/* All done */
362 	if (result)
363 	{
364 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
365 	}
366 	else
367 	{
368 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
369 	}
370 
371 	return STOP;
372 }
373 
374 /** Constructor
375  *
376  * @param context       Test context
377  * @param extParams     Not used.
378  * @param name          Test case's name
379  * @param description   Test case's description
380  **/
GeometryShaderIncompleteLayeredAttachmentsTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)381 GeometryShaderIncompleteLayeredAttachmentsTest::GeometryShaderIncompleteLayeredAttachmentsTest(
382 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
383 	: TestCaseBase(context, extParams, name, description), m_fbo_ids(DE_NULL), m_to_ids(DE_NULL)
384 {
385 	// left blank intentionally
386 }
387 
388 /** Deinitializes GLES objects created during the test. */
deinit()389 void GeometryShaderIncompleteLayeredAttachmentsTest::deinit()
390 {
391 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
392 
393 	/* Release framebuffer objects */
394 	GeometryShaderLayeredFBOShared::deinitFBOs(gl, m_fbo_ids);
395 
396 	if (m_fbo_ids != DE_NULL)
397 	{
398 		delete[] m_fbo_ids;
399 
400 		m_fbo_ids = DE_NULL;
401 	}
402 
403 	/* Release texture objects */
404 	GeometryShaderLayeredFBOShared::deinitTOs(gl, m_to_ids);
405 
406 	if (m_to_ids != DE_NULL)
407 	{
408 		delete[] m_to_ids;
409 
410 		m_to_ids = DE_NULL;
411 	}
412 
413 	/* Release base class */
414 	TestCaseBase::deinit();
415 }
416 
417 /** Executes the test.
418  *
419  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
420  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
421  *  Note the function throws exception should an error occur!
422  **/
iterate()423 tcu::TestNode::IterateResult GeometryShaderIncompleteLayeredAttachmentsTest::iterate()
424 {
425 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
426 	bool				  result = true;
427 
428 	/* This test should only run if EXT_geometry_shader is supported. */
429 	if (!m_is_geometry_shader_extension_supported)
430 	{
431 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
432 	}
433 
434 	/* Set up texture objects */
435 	m_to_ids = new glw::GLuint[GeometryShaderLayeredFBOShared::n_shared_to_ids];
436 
437 	GeometryShaderLayeredFBOShared::initTOs(gl, gl.texStorage3DMultisample, m_to_ids);
438 
439 	/* Set up framebuffer objects */
440 	m_fbo_ids = new glw::GLuint[GeometryShaderLayeredFBOShared::n_shared_fbo_ids];
441 
442 	GeometryShaderLayeredFBOShared::initFBOs(gl, gl.framebufferTexture, m_to_ids, m_fbo_ids);
443 
444 	/* Verify query results for FBO A attachments - as per test spec */
445 	glw::GLint is_fbo_color_attachment0_layered = GL_TRUE;
446 	glw::GLint is_fbo_color_attachment1_layered = GL_TRUE;
447 	glw::GLint is_fbo_color_attachment2_layered = GL_TRUE;
448 	glw::GLint is_fbo_depth_attachment_layered  = GL_TRUE;
449 
450 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_ids[0]);
451 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
452 
453 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
454 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
455 										   &is_fbo_color_attachment0_layered);
456 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2,
457 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
458 										   &is_fbo_color_attachment2_layered);
459 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
460 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
461 										   &is_fbo_depth_attachment_layered);
462 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferAttachmentParameteriv() call failed.");
463 
464 	if (is_fbo_color_attachment0_layered != GL_FALSE || is_fbo_color_attachment2_layered != GL_TRUE ||
465 		is_fbo_depth_attachment_layered != GL_FALSE)
466 	{
467 		m_testCtx.getLog() << tcu::TestLog::Message
468 						   << "Invalid GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT query results retrieved for FBO A"
469 						   << tcu::TestLog::EndMessage;
470 
471 		result = false;
472 	}
473 
474 	/* Verify query results for FBO B attachments - as per test spec */
475 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_ids[1]);
476 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
477 
478 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
479 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
480 										   &is_fbo_color_attachment0_layered);
481 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
482 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
483 										   &is_fbo_color_attachment1_layered);
484 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2,
485 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
486 										   &is_fbo_color_attachment2_layered);
487 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferAttachmentParameteriv() call failed.");
488 
489 	if (is_fbo_color_attachment0_layered != GL_TRUE || is_fbo_color_attachment1_layered != GL_FALSE ||
490 		is_fbo_color_attachment2_layered != GL_TRUE)
491 	{
492 		m_testCtx.getLog() << tcu::TestLog::Message
493 						   << "Invalid GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT query results retrieved for FBO B"
494 						   << tcu::TestLog::EndMessage;
495 
496 		result = false;
497 	}
498 
499 	/* Verify query results for FBO C attachments - as per test spec */
500 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_ids[2]);
501 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
502 
503 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
504 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
505 										   &is_fbo_color_attachment0_layered);
506 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
507 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
508 										   &is_fbo_depth_attachment_layered);
509 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetFramebufferAttachmentParameteriv() call failed.");
510 
511 	if (is_fbo_color_attachment0_layered != GL_TRUE || is_fbo_depth_attachment_layered != GL_FALSE)
512 	{
513 		m_testCtx.getLog() << tcu::TestLog::Message
514 						   << "Invalid GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT query results retrieved for FBO C"
515 						   << tcu::TestLog::EndMessage;
516 
517 		result = false;
518 	}
519 
520 	/* Verify query results for FBO D attachments - as per test spec */
521 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_ids[3]);
522 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
523 
524 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
525 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
526 										   &is_fbo_color_attachment0_layered);
527 	gl.getFramebufferAttachmentParameteriv(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
528 										   m_glExtTokens.FRAMEBUFFER_ATTACHMENT_LAYERED,
529 										   &is_fbo_color_attachment1_layered);
530 
531 	if (is_fbo_color_attachment0_layered != GL_FALSE || is_fbo_color_attachment1_layered != GL_TRUE)
532 	{
533 		m_testCtx.getLog() << tcu::TestLog::Message
534 						   << "Invalid GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT query results retrieved for FBO D"
535 						   << tcu::TestLog::EndMessage;
536 
537 		result = false;
538 	}
539 
540 	/* All done */
541 	if (result)
542 	{
543 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
544 	}
545 	else
546 	{
547 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
548 	}
549 
550 	return STOP;
551 }
552 
553 /** Constructor
554  *
555  * @param context       Test context
556  * @param extParams     Not used.
557  * @param name          Test case's name
558  * @param description   Test case's description
559  **/
GeometryShaderFramebufferTextureInvalidTarget(Context & context,const ExtParameters & extParams,const char * name,const char * description)560 GeometryShaderFramebufferTextureInvalidTarget::GeometryShaderFramebufferTextureInvalidTarget(
561 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
562 	: TestCaseBase(context, extParams, name, description), m_fbo_id(0), m_to_id(0)
563 {
564 }
565 
566 /** Deinitializes GLES objects created during the test. */
deinit()567 void GeometryShaderFramebufferTextureInvalidTarget::deinit()
568 {
569 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
570 
571 	if (m_fbo_id != 0)
572 	{
573 		gl.deleteFramebuffers(1, &m_fbo_id);
574 		m_fbo_id = 0;
575 	}
576 
577 	if (m_to_id != 0)
578 	{
579 		gl.deleteTextures(1, &m_to_id);
580 		m_to_id = 0;
581 	}
582 
583 	/* Release base class */
584 	TestCaseBase::deinit();
585 }
586 
587 /** Executes the test.
588  *
589  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
590  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
591  *  Note the function throws exception should an error occur!
592  **/
iterate()593 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureInvalidTarget::iterate()
594 {
595 	bool result = true;
596 
597 	/* This test should only run if EXT_geometry_shader is supported. */
598 	if (!m_is_geometry_shader_extension_supported)
599 	{
600 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
601 	}
602 
603 	const glw::GLubyte pixels[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
604 
605 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
606 
607 	gl.genTextures(1, &m_to_id);
608 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
609 
610 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
611 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
612 
613 	gl.texImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, 2 /* width */, 2 /* height */, 0 /* border */, GL_RGBA,
614 				  GL_UNSIGNED_BYTE, pixels);
615 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D() call failed.");
616 
617 	gl.generateMipmap(GL_TEXTURE_2D);
618 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed.");
619 
620 	gl.genFramebuffers(1, &m_fbo_id);
621 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
622 
623 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
624 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed with GL_DRAW_FRAMEBUFFER pname.");
625 
626 	glw::GLuint errorEnum;
627 
628 	gl.framebufferTexture(GL_TEXTURE_3D, GL_COLOR_ATTACHMENT0, m_to_id /* texture */, 1 /* level */);
629 	errorEnum = gl.getError();
630 
631 	if (errorEnum != GL_INVALID_ENUM)
632 	{
633 		result = false;
634 
635 		m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_ENUM was generated."
636 						   << tcu::TestLog::EndMessage;
637 	}
638 
639 	if (result)
640 	{
641 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
642 	}
643 	else
644 	{
645 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
646 	}
647 
648 	return STOP;
649 }
650 
651 /** Constructor
652  *
653  * @param context       Test context
654  * @param extParams     Not used.
655  * @param name          Test case's name
656  * @param description   Test case's description
657  **/
GeometryShaderFramebufferTextureNoFBOBoundToTarget(Context & context,const ExtParameters & extParams,const char * name,const char * description)658 GeometryShaderFramebufferTextureNoFBOBoundToTarget::GeometryShaderFramebufferTextureNoFBOBoundToTarget(
659 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
660 	: TestCaseBase(context, extParams, name, description), m_to_id(0)
661 {
662 }
663 
664 /** Deinitializes GLES objects created during the test. */
deinit()665 void GeometryShaderFramebufferTextureNoFBOBoundToTarget::deinit()
666 {
667 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
668 
669 	if (m_to_id != 0)
670 	{
671 		gl.deleteTextures(1, &m_to_id);
672 		m_to_id = 0;
673 	}
674 
675 	/* Release base class */
676 	TestCaseBase::deinit();
677 }
678 
679 /** Executes the test.
680  *
681  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
682  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
683  *  Note the function throws exception should an error occur!
684  **/
iterate()685 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureNoFBOBoundToTarget::iterate()
686 {
687 	const glw::GLuint fbEnums[] = { GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER };
688 
689 	const size_t numberOfEnums = sizeof(fbEnums) / sizeof(fbEnums[0]);
690 
691 	bool result = false;
692 
693 	/* This test should only run if EXT_geometry_shader is supported. */
694 	if (!m_is_geometry_shader_extension_supported)
695 	{
696 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
697 	}
698 
699 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
700 
701 	gl.genTextures(1, &m_to_id);
702 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
703 
704 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
705 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
706 
707 	glw::GLuint errorEnum;
708 
709 	for (size_t i = 0; i < numberOfEnums; ++i)
710 	{
711 		gl.bindFramebuffer(fbEnums[i], 0 /* framebuffer */);
712 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
713 
714 		gl.framebufferTexture(fbEnums[i], GL_COLOR_ATTACHMENT0, m_to_id /* texture */, 1 /* level */);
715 		errorEnum = gl.getError();
716 
717 		if (errorEnum == GL_INVALID_OPERATION)
718 		{
719 			result = true;
720 		}
721 		else
722 		{
723 			result = false;
724 
725 			m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPERATION was generated."
726 							   << tcu::TestLog::EndMessage;
727 
728 			break;
729 		}
730 	}
731 
732 	if (result)
733 	{
734 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
735 	}
736 	else
737 	{
738 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
739 	}
740 
741 	return STOP;
742 }
743 
744 /** Constructor
745  *
746  * @param context       Test context
747  * @param extParams     Not used.
748  * @param name          Test case's name
749  * @param description   Test case's description
750  **/
GeometryShaderFramebufferTextureInvalidAttachment(Context & context,const ExtParameters & extParams,const char * name,const char * description)751 GeometryShaderFramebufferTextureInvalidAttachment::GeometryShaderFramebufferTextureInvalidAttachment(
752 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
753 	: TestCaseBase(context, extParams, name, description), m_fbo_id(0), m_to_id(0)
754 {
755 }
756 
757 /** Deinitializes GLES objects created during the test. */
deinit()758 void GeometryShaderFramebufferTextureInvalidAttachment::deinit()
759 {
760 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
761 
762 	if (m_fbo_id != 0)
763 	{
764 		gl.deleteFramebuffers(1, &m_fbo_id);
765 		m_fbo_id = 0;
766 	}
767 
768 	if (m_to_id != 0)
769 	{
770 		gl.deleteTextures(1, &m_to_id);
771 		m_to_id = 0;
772 	}
773 
774 	/* Release base class */
775 	TestCaseBase::deinit();
776 }
777 
778 /** Executes the test.
779  *
780  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
781  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
782  *  Note the function throws exception should an error occur!
783  **/
iterate()784 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureInvalidAttachment::iterate()
785 {
786 	const glw::GLuint fbEnums[] = { GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER };
787 
788 	const size_t numberOfEnums = sizeof(fbEnums) / sizeof(fbEnums[0]);
789 
790 	bool result = false;
791 
792 	/* This test should only run if EXT_geometry_shader is supported. */
793 	if (!m_is_geometry_shader_extension_supported)
794 	{
795 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
796 	}
797 
798 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
799 
800 	glw::GLuint errorEnum;
801 	glw::GLint  maxColorAttachments = 0;
802 
803 	gl.genFramebuffers(1, &m_fbo_id);
804 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
805 
806 	gl.genTextures(1, &m_to_id);
807 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
808 
809 	gl.bindTexture(GL_TEXTURE_2D, m_to_id);
810 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
811 
812 	gl.getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
813 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed with pname GL_MAX_COLOR_ATTACHMENTS.");
814 
815 	for (size_t i = 0; i < numberOfEnums; ++i)
816 	{
817 		gl.bindFramebuffer(fbEnums[i], m_fbo_id);
818 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
819 
820 		gl.framebufferTexture(fbEnums[i], GL_COLOR_ATTACHMENT0 + maxColorAttachments, m_to_id /* texture */,
821 							  0 /* level */);
822 		errorEnum = gl.getError();
823 
824 		if (errorEnum == GL_INVALID_OPERATION)
825 		{
826 			result = true;
827 		}
828 		else
829 		{
830 			result = false;
831 
832 			m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPERATION was generated."
833 							   << tcu::TestLog::EndMessage;
834 
835 			break;
836 		}
837 	}
838 
839 	if (result)
840 	{
841 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
842 	}
843 	else
844 	{
845 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
846 	}
847 
848 	return STOP;
849 }
850 
851 /** Constructor
852  *
853  * @param context       Test context
854  * @param extParams     Not used.
855  * @param name          Test case's name
856  * @param description   Test case's description
857  **/
GeometryShaderFramebufferTextureInvalidValue(Context & context,const ExtParameters & extParams,const char * name,const char * description)858 GeometryShaderFramebufferTextureInvalidValue::GeometryShaderFramebufferTextureInvalidValue(
859 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
860 	: TestCaseBase(context, extParams, name, description), m_fbo_id(0)
861 {
862 }
863 
864 /** Deinitializes GLES objects created during the test. */
deinit()865 void GeometryShaderFramebufferTextureInvalidValue::deinit()
866 {
867 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
868 
869 	if (m_fbo_id != 0)
870 	{
871 		gl.deleteFramebuffers(1, &m_fbo_id);
872 		m_fbo_id = 0;
873 	}
874 
875 	/* Release base class */
876 	TestCaseBase::deinit();
877 }
878 
879 /** Executes the test.
880  *
881  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
882  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
883  *  Note the function throws exception should an error occur!
884  **/
iterate()885 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureInvalidValue::iterate()
886 {
887 	const glw::GLuint fbEnums[]		= { GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER };
888 	const size_t	  numberOfEnums = sizeof(fbEnums) / sizeof(fbEnums[0]);
889 	bool			  result		= false;
890 
891 	/* This test should only run if EXT_geometry_shader is supported. */
892 	if (!m_is_geometry_shader_extension_supported)
893 	{
894 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
895 	}
896 
897 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
898 
899 	gl.genFramebuffers(1, &m_fbo_id);
900 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
901 
902 	glw::GLuint errorEnum;
903 	glw::GLuint invalidValue = 1;
904 
905 	for (size_t i = 0; i < numberOfEnums; ++i)
906 	{
907 		gl.bindFramebuffer(fbEnums[i], m_fbo_id);
908 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
909 
910 		gl.framebufferTexture(fbEnums[i], GL_COLOR_ATTACHMENT0, invalidValue /* texture */, 1 /* level */);
911 		errorEnum = gl.getError();
912 
913 		invalidValue *= 10;
914 
915 		if (errorEnum == GL_INVALID_VALUE)
916 		{
917 			result = true;
918 		}
919 		else
920 		{
921 			result = false;
922 
923 			m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_VALUE was generated."
924 							   << tcu::TestLog::EndMessage;
925 
926 			break;
927 		}
928 	}
929 
930 	if (result)
931 	{
932 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
933 	}
934 	else
935 	{
936 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
937 	}
938 
939 	return STOP;
940 }
941 
942 /** Constructor
943  *
944  * @param context       Test context
945  * @param extParams     Not used.
946  * @param name          Test case's name
947  * @param description   Test case's description
948  **/
GeometryShaderFramebufferTextureInvalidLevelNumber(Context & context,const ExtParameters & extParams,const char * name,const char * description)949 GeometryShaderFramebufferTextureInvalidLevelNumber::GeometryShaderFramebufferTextureInvalidLevelNumber(
950 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
951 	: TestCaseBase(context, extParams, name, description)
952 	, m_fbo_id(0)
953 	, m_tex_depth(4)
954 	, m_tex_height(4)
955 	, m_tex_width(4)
956 	, m_to_2d_array_id(0)
957 	, m_to_3d_id(0)
958 {
959 	/* Allocate memory for m_tex_depth * m_tex_height * m_tex_width texels, with each texel being 4 GLubytes. */
960 	m_texels = new glw::GLubyte[m_tex_depth * m_tex_height * m_tex_width * 4];
961 
962 	memset(m_texels, 255, m_tex_depth * m_tex_height * m_tex_width * 4);
963 }
964 
965 /** Deinitializes GLES objects created during the test. */
deinit()966 void GeometryShaderFramebufferTextureInvalidLevelNumber::deinit()
967 {
968 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
969 
970 	if (m_fbo_id != 0)
971 	{
972 		gl.deleteFramebuffers(1, &m_fbo_id);
973 		m_fbo_id = 0;
974 
975 		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
976 	}
977 
978 	if (m_texels != NULL)
979 	{
980 		delete[] m_texels;
981 		m_texels = NULL;
982 	}
983 
984 	if (m_to_2d_array_id != 0)
985 	{
986 		gl.deleteTextures(1, &m_to_2d_array_id);
987 		m_to_2d_array_id = 0;
988 	}
989 
990 	if (m_to_3d_id != 0)
991 	{
992 		gl.deleteTextures(1, &m_to_3d_id);
993 		m_to_3d_id = 0;
994 	}
995 
996 	/* Release base class */
997 	TestCaseBase::deinit();
998 }
999 
1000 /** Executes the test.
1001  *
1002  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1003  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1004  *  Note the function throws exception should an error occur!
1005  **/
iterate()1006 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureInvalidLevelNumber::iterate()
1007 {
1008 	bool result = false;
1009 
1010 	/* This test should only run if EXT_geometry_shader is supported. */
1011 	if (!m_is_geometry_shader_extension_supported)
1012 	{
1013 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1014 	}
1015 
1016 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1017 
1018 	/* Generate and bind framebuffer object */
1019 	gl.genFramebuffers(1, &m_fbo_id);
1020 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
1021 
1022 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
1023 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
1024 
1025 	/* Prepare texture 3D and generate its mipmaps */
1026 	gl.genTextures(1, &m_to_3d_id);
1027 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
1028 
1029 	gl.bindTexture(GL_TEXTURE_3D, m_to_3d_id);
1030 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
1031 
1032 	gl.texStorage3D(GL_TEXTURE_3D, 2 /* levels */, GL_RGBA8, m_tex_width, m_tex_height, m_tex_depth);
1033 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
1034 
1035 	gl.texSubImage3D(GL_TEXTURE_3D, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, m_tex_width,
1036 					 m_tex_height, m_tex_depth, GL_RGBA, GL_UNSIGNED_BYTE, m_texels);
1037 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed.");
1038 
1039 	gl.generateMipmap(GL_TEXTURE_3D);
1040 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed with pname GL_TEXTURE_3D.");
1041 
1042 	/* Prepare texture array 2D */
1043 	gl.genTextures(1, &m_to_2d_array_id);
1044 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
1045 
1046 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_2d_array_id);
1047 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
1048 
1049 	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 2 /* levels */, GL_RGBA8, m_tex_width, m_tex_height,
1050 					m_tex_depth /* layerCount */);
1051 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage3D() call failed.");
1052 
1053 	gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0 /* level */, 0 /* xoffset */, 0 /* yoffset */, 0 /* zoffset */, m_tex_width,
1054 					 m_tex_height, m_tex_depth, GL_RGBA, GL_UNSIGNED_BYTE, m_texels);
1055 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed.");
1056 
1057 	gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
1058 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap() call failed with pname GL_TEXTURE_2D_ARRAY.");
1059 
1060 	glw::GLuint errorEnum;
1061 
1062 	/* Test for texture 3D */
1063 	gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_3d_id /* texture */, 2 /* level */);
1064 	errorEnum = gl.getError();
1065 
1066 	if (errorEnum == GL_INVALID_VALUE)
1067 	{
1068 		result = true;
1069 	}
1070 	else
1071 	{
1072 		result = false;
1073 
1074 		m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_VALUE was generated."
1075 						   << tcu::TestLog::EndMessage;
1076 
1077 		goto end;
1078 	}
1079 
1080 	/* Test for texture array 2D */
1081 	gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_2d_array_id /* texture */, 2 /* level */);
1082 	errorEnum = gl.getError();
1083 
1084 	if (errorEnum == GL_INVALID_VALUE)
1085 	{
1086 		result = true;
1087 	}
1088 	else
1089 	{
1090 		result = false;
1091 
1092 		m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_VALUE was generated."
1093 						   << tcu::TestLog::EndMessage;
1094 
1095 		goto end;
1096 	}
1097 
1098 end:
1099 	if (result)
1100 	{
1101 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1102 	}
1103 	else
1104 	{
1105 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1106 	}
1107 
1108 	return STOP;
1109 }
1110 
1111 /** Constructor
1112  *
1113  * @param context       Test context
1114  * @param extParams     Not used.
1115  * @param name          Test case's name
1116  * @param description   Test case's description
1117  **/
1118 GeometryShaderFramebufferTextureArgumentRefersToBufferTexture::
GeometryShaderFramebufferTextureArgumentRefersToBufferTexture(Context & context,const ExtParameters & extParams,const char * name,const char * description)1119 	GeometryShaderFramebufferTextureArgumentRefersToBufferTexture(Context& context, const ExtParameters& extParams,
1120 																  const char* name, const char* description)
1121 	: TestCaseBase(context, extParams, name, description), m_bo_id(0), m_fbo_id(0), m_tbo_id(0)
1122 {
1123 	m_tex_width  = 64;
1124 	m_tex_height = 64;
1125 
1126 	/* Allocate memory for m_tex_height * m_tex_width texels, with each texel being 3 GLints. */
1127 	m_texels = new glw::GLint[m_tex_height * m_tex_width * 3];
1128 
1129 	memset(m_texels, 255, sizeof(glw::GLint) * m_tex_height * m_tex_width * 3);
1130 }
1131 
1132 /** Deinitializes GLES objects created during the test. */
deinit()1133 void GeometryShaderFramebufferTextureArgumentRefersToBufferTexture::deinit()
1134 {
1135 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1136 
1137 	if (m_bo_id != 0)
1138 	{
1139 		gl.deleteBuffers(1, &m_bo_id);
1140 		m_bo_id = 0;
1141 	}
1142 
1143 	if (m_fbo_id != 0)
1144 	{
1145 		gl.deleteFramebuffers(1, &m_fbo_id);
1146 		m_fbo_id = 0;
1147 
1148 		gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1149 	}
1150 
1151 	if (m_tbo_id != 0)
1152 	{
1153 		gl.deleteTextures(1, &m_tbo_id);
1154 		m_tbo_id = 0;
1155 	}
1156 
1157 	if (m_texels != NULL)
1158 	{
1159 		delete[] m_texels;
1160 		m_texels = NULL;
1161 	}
1162 
1163 	/* Release base class */
1164 	TestCaseBase::deinit();
1165 }
1166 
1167 /** Executes the test.
1168  *
1169  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1170  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1171  *  Note the function throws exception should an error occur!
1172  **/
iterate()1173 tcu::TestNode::IterateResult GeometryShaderFramebufferTextureArgumentRefersToBufferTexture::iterate()
1174 {
1175 	bool result = false;
1176 
1177 	/* This test should only run if EXT_geometry_shader and EXT_texture_buffer are supported. */
1178 	if (!m_is_geometry_shader_extension_supported)
1179 	{
1180 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1181 	}
1182 
1183 	if (!m_is_texture_buffer_supported)
1184 	{
1185 		throw tcu::NotSupportedError(TEXTURE_BUFFER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1186 	}
1187 
1188 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1189 
1190 	/* Generate buffer object */
1191 	gl.genBuffers(1, &m_bo_id);
1192 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
1193 
1194 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
1195 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
1196 
1197 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(m_texels), m_texels, GL_DYNAMIC_READ);
1198 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
1199 
1200 	/* Generate and bind framebuffer object */
1201 	gl.genFramebuffers(1, &m_fbo_id);
1202 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
1203 
1204 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
1205 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
1206 
1207 	/* Prepare texture buffer */
1208 	gl.genTextures(1, &m_tbo_id);
1209 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
1210 
1211 	gl.bindTexture(GL_TEXTURE_BUFFER, m_tbo_id);
1212 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
1213 
1214 	gl.texBuffer(GL_TEXTURE_BUFFER, GL_RGB32I, m_bo_id);
1215 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexBuffer() call failed.");
1216 
1217 	glw::GLuint errorEnum;
1218 
1219 	/* Test for texture 3D */
1220 	gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_tbo_id /* texture */, 0 /* level */);
1221 	errorEnum = gl.getError();
1222 
1223 	if (errorEnum == GL_INVALID_OPERATION)
1224 	{
1225 		result = true;
1226 	}
1227 	else
1228 	{
1229 		result = false;
1230 
1231 		m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPERATION was generated."
1232 						   << tcu::TestLog::EndMessage;
1233 
1234 		goto end;
1235 	}
1236 
1237 end:
1238 	if (result)
1239 	{
1240 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1241 	}
1242 	else
1243 	{
1244 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1245 	}
1246 
1247 	return STOP;
1248 }
1249 
1250 } // namespace glcts
1251