• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */ /*!
20  * \file
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "esextcGeometryShaderLayeredRenderingFBONoAttachment.hpp"
25 
26 #include "gluDefs.hpp"
27 #include "tcuTestLog.hpp"
28 
29 namespace glcts
30 {
31 /* Fragment shader code */
32 const char* GeometryShaderLayeredRenderingFBONoAttachment::m_fs_code =
33 	"${VERSION}\n"
34 	"\n"
35 	"${GEOMETRY_SHADER_REQUIRE}\n"
36 	"\n"
37 	"precision highp float;\n"
38 	"\n"
39 	"layout(rgba32i, binding = 0) writeonly uniform highp iimage2DArray array_image;\n"
40 	"\n"
41 	"     in  vec2 uv;\n"
42 	"flat in  int  layer_id;\n"
43 	"out vec4 color;\n"
44 	"\n"
45 	"void main()\n"
46 	"{\n"
47 	"    imageStore(array_image, ivec3( int(128.0 * uv.x), int(128.0 * uv.y), layer_id ), ivec4(0, 255, 0, 0) );\n"
48 	"}\n";
49 
50 /* Geometry shader code */
51 const char* GeometryShaderLayeredRenderingFBONoAttachment::m_gs_code = "${VERSION}\n"
52 																	   "\n"
53 																	   "${GEOMETRY_SHADER_REQUIRE}\n"
54 																	   "\n"
55 																	   "precision highp float;\n"
56 																	   "\n"
57 																	   "layout(points)                          in;\n"
58 																	   "layout(triangle_strip, max_vertices=16) out;\n"
59 																	   "\n"
60 																	   "     out vec2 uv;\n"
61 																	   "flat out int  layer_id;\n"
62 																	   "\n"
63 																	   "void main()\n"
64 																	   "{\n"
65 																	   "    for (int n = 0; n < 4; ++n)\n"
66 																	   "    {\n"
67 																	   "        gl_Position = vec4(1, -1, 0, 1);\n"
68 																	   "        gl_Layer    = n;\n"
69 																	   "        layer_id    = n;\n"
70 																	   "        uv          = vec2(1, 0);\n"
71 																	   "        EmitVertex();\n"
72 																	   "\n"
73 																	   "        gl_Position = vec4(1,  1, 0, 1);\n"
74 																	   "        gl_Layer    = n;\n"
75 																	   "        layer_id    = n;\n"
76 																	   "        uv          = vec2(1, 1);\n"
77 																	   "        EmitVertex();\n"
78 																	   "\n"
79 																	   "        gl_Position = vec4(-1, -1, 0, 1);\n"
80 																	   "        gl_Layer    = n;\n"
81 																	   "        layer_id    = n;\n"
82 																	   "        uv          = vec2(0, 0);\n"
83 																	   "        EmitVertex();\n"
84 																	   "\n"
85 																	   "        gl_Position = vec4(-1,  1, 0, 1);\n"
86 																	   "        gl_Layer    = n;\n"
87 																	   "        layer_id    = n;\n"
88 																	   "        uv          = vec2(0, 1);\n"
89 																	   "        EmitVertex();\n"
90 																	   "\n"
91 																	   "        EndPrimitive();\n"
92 																	   "    }\n"
93 																	   "}\n";
94 
95 /* Vertex shader code */
96 const char* GeometryShaderLayeredRenderingFBONoAttachment::m_vs_code = "${VERSION}\n"
97 																	   "\n"
98 																	   "${GEOMETRY_SHADER_REQUIRE}\n"
99 																	   "\n"
100 																	   "precision highp float;\n"
101 																	   "\n"
102 																	   "void main()\n"
103 																	   "{\n"
104 																	   "}\n";
105 
106 /* Constants */
107 const glw::GLint GeometryShaderLayeredRenderingFBONoAttachment::m_height			   = 128;
108 const glw::GLint GeometryShaderLayeredRenderingFBONoAttachment::m_width				   = 128;
109 const int		 GeometryShaderLayeredRenderingFBONoAttachment::m_n_layers			   = 4;
110 const glw::GLint GeometryShaderLayeredRenderingFBONoAttachment::m_n_texture_components = 4;
111 
112 /** Constructor
113  *
114  * @param context       Test context
115  * @param name          Test case's name
116  * @param description   Test case's description
117  **/
GeometryShaderLayeredRenderingFBONoAttachment(Context & context,const ExtParameters & extParams,const char * name,const char * description)118 GeometryShaderLayeredRenderingFBONoAttachment::GeometryShaderLayeredRenderingFBONoAttachment(
119 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
120 	: TestCaseBase(context, extParams, name, description)
121 	, m_fbo_id(0)
122 	, m_fs_id(0)
123 	, m_gs_id(0)
124 	, m_po_id(0)
125 	, m_to_id(0)
126 	, m_vao_id(0)
127 	, m_vs_id(0)
128 	, m_all_layers_data(DE_NULL)
129 	, m_layer_data(DE_NULL)
130 {
131 	/* Nothing to be done here */
132 }
133 
134 /** Deinitializes GLES objects created during the test.
135  *
136  */
deinit(void)137 void GeometryShaderLayeredRenderingFBONoAttachment::deinit(void)
138 {
139 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
140 
141 	/* Reset OpenGL ES state */
142 	gl.useProgram(0);
143 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0 /* texture */);
144 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
145 	gl.bindVertexArray(0);
146 
147 	if (m_po_id != 0)
148 	{
149 		gl.deleteProgram(m_po_id);
150 		m_po_id = 0;
151 	}
152 
153 	if (m_fs_id != 0)
154 	{
155 		gl.deleteShader(m_fs_id);
156 		m_fs_id = 0;
157 	}
158 
159 	if (m_gs_id != 0)
160 	{
161 		gl.deleteShader(m_gs_id);
162 		m_gs_id = 0;
163 	}
164 
165 	if (m_vs_id != 0)
166 	{
167 		gl.deleteShader(m_vs_id);
168 		m_vs_id = 0;
169 	}
170 
171 	if (m_to_id != 0)
172 	{
173 		gl.deleteTextures(1, &m_to_id);
174 		m_to_id = 0;
175 	}
176 
177 	if (m_fbo_id != 0)
178 	{
179 		gl.deleteFramebuffers(1, &m_fbo_id);
180 		m_fbo_id = 0;
181 	}
182 
183 	if (m_vao_id != 0)
184 	{
185 		gl.deleteVertexArrays(1, &m_vao_id);
186 		m_vao_id = 0;
187 	}
188 
189 	if (m_all_layers_data != DE_NULL)
190 	{
191 		delete[] m_all_layers_data;
192 		m_all_layers_data = DE_NULL;
193 	}
194 
195 	if (m_layer_data != DE_NULL)
196 	{
197 		delete[] m_layer_data;
198 		m_layer_data = DE_NULL;
199 	}
200 
201 	/* Release base class */
202 	TestCaseBase::deinit();
203 }
204 
205 /** Executes the test.
206  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
207  *
208  *  Note the function throws exception should an error occur!
209  *
210  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
211  *
212  **/
iterate(void)213 tcu::TestNode::IterateResult GeometryShaderLayeredRenderingFBONoAttachment::iterate(void)
214 {
215 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
216 
217 	/* Check if required extensions are supported */
218 	if (!m_is_geometry_shader_extension_supported)
219 	{
220 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
221 	}
222 
223 	if (!m_is_framebuffer_no_attachments_supported)
224 	{
225 		throw tcu::NotSupportedError("framebuffer_no_attachment, is not supported", "", __FILE__, __LINE__);
226 	}
227 
228 	if (!m_is_shader_image_load_store_supported)
229 	{
230 		throw tcu::NotSupportedError("shader_image_load_store, is not supported", "", __FILE__, __LINE__);
231 	}
232 
233 	/* Generate and bind a framebuffer object */
234 	gl.genFramebuffers(1, &m_fbo_id);
235 	gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo_id);
236 
237 	/* Get the default number of layers of a newly created framebuffer object */
238 	glw::GLint nLayers = -1;
239 
240 	gl.getFramebufferParameteriv(GL_DRAW_FRAMEBUFFER, m_glExtTokens.FRAMEBUFFER_DEFAULT_LAYERS, &nLayers);
241 
242 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not query a framebuffer object for the number of default layers!");
243 
244 	/* check 14.2 test condition - if default number of layer equals 0 */
245 	if (nLayers != 0)
246 	{
247 		m_testCtx.getLog() << tcu::TestLog::Message << "Number of default layers should be equal to 0 but is "
248 						   << nLayers << tcu::TestLog::EndMessage;
249 
250 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
251 		return STOP;
252 	}
253 
254 	/* Set the default resolution to 128x128 */
255 	glw::GLint width  = 0;
256 	glw::GLint height = 0;
257 
258 	gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, m_width);
259 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set the default framebuffer's width!");
260 	gl.getFramebufferParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, &width);
261 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get the default framebuffer's width!");
262 	gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, m_height);
263 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set the default framebuffer's height!");
264 	gl.getFramebufferParameteriv(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, &height);
265 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not get the default framebuffer's height!");
266 
267 	if (m_width != width || m_height != height)
268 	{
269 		m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer's default width/height is not equal to" << m_width
270 						   << "\\" << m_height << " but is " << width << "\\" << height << tcu::TestLog::EndMessage;
271 
272 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
273 		return STOP;
274 	}
275 
276 	/* Configure program object to be used for functional part of the test */
277 	m_po_id = gl.createProgram();
278 
279 	m_vs_id = gl.createShader(GL_VERTEX_SHADER);
280 	m_gs_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
281 	m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
282 
283 	if (!buildProgram(m_po_id, m_fs_id, 1 /* part */, &m_fs_code, m_gs_id, 1 /* part */, &m_gs_code, m_vs_id,
284 					  1 /* part */, &m_vs_code))
285 	{
286 		TCU_FAIL("Could not create program object from a valid vertex/geometry/fragment shader code!");
287 	}
288 
289 	/* Configure texture objects and fill them with initial data */
290 	m_all_layers_data = new glw::GLint[m_n_layers * m_width * m_height * m_n_texture_components];
291 
292 	for (int n = 0; n < m_n_layers * m_width * m_height; ++n)
293 	{
294 		m_all_layers_data[n * m_n_texture_components + 0] = 255;
295 		m_all_layers_data[n * m_n_texture_components + 1] = 0;
296 		m_all_layers_data[n * m_n_texture_components + 2] = 0;
297 		m_all_layers_data[n * m_n_texture_components + 3] = 0;
298 	}
299 
300 	gl.genTextures(1, &m_to_id);
301 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_to_id);
302 	gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1 /* levels */, GL_RGBA32I, m_width, m_height, m_n_layers);
303 	gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
304 	gl.texParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
305 
306 	GLU_EXPECT_NO_ERROR(gl.getError(), "Error creating texture objects!");
307 
308 	/* Activate the test program object */
309 	gl.useProgram(m_po_id);
310 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program!");
311 
312 	/* Bind texture to image unit */
313 	gl.bindImageTexture(0, m_to_id, 0 /* level */, GL_TRUE, 0 /* layer */, GL_WRITE_ONLY, GL_RGBA32I);
314 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind texture to image unit!");
315 
316 	/* Generate & bind a VAO */
317 	gl.genVertexArrays(1, &m_vao_id);
318 	gl.bindVertexArray(m_vao_id);
319 
320 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create a vertex array object!");
321 
322 	/* Set up the viewport */
323 	gl.viewport(0 /* x */, 0 /* y */, m_width /* width */, m_height /* height */);
324 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
325 
326 	/* Test 21.4 adjusts the behavior of the original tests. The test now needs to run
327 	 * in two iterations:
328 	 *
329 	 * a) Original behavior is left intact
330 	 * b) GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT should be set to 0.
331 	 */
332 	glw::GLboolean test_failed = false;
333 
334 	m_layer_data = new glw::GLint[m_width * m_height * m_n_texture_components];
335 
336 	for (unsigned int n_test_iteration = 0; n_test_iteration < 2 && !test_failed; ++n_test_iteration)
337 	{
338 		const glw::GLint current_n_layers = (n_test_iteration == 1) ? 0 : m_n_layers;
339 
340 		/* Reset render-target contents */
341 		gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, /* level   */
342 						 0,						 /* xoffset */
343 						 0,						 /* yoffset */
344 						 0,						 /* zoffset */
345 						 m_width, m_height, m_n_layers, GL_RGBA_INTEGER, GL_INT, m_all_layers_data);
346 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage3D() call failed.");
347 
348 		/* Set the default number of layers to m_n_layers */
349 		gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, m_glExtTokens.FRAMEBUFFER_DEFAULT_LAYERS, current_n_layers);
350 
351 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set the default number of layers of a framebuffer object!");
352 
353 		gl.getFramebufferParameteriv(GL_DRAW_FRAMEBUFFER, m_glExtTokens.FRAMEBUFFER_DEFAULT_LAYERS, &nLayers);
354 
355 		/* check if the reported value equals m_n_layers */
356 		if (current_n_layers != nLayers)
357 		{
358 			m_testCtx.getLog() << tcu::TestLog::Message << "FBO's default layers should be equal to " << m_n_layers
359 							   << "but is " << nLayers << tcu::TestLog::EndMessage;
360 
361 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
362 			return STOP;
363 		}
364 
365 		/* Render! */
366 		gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
367 
368 		GLU_EXPECT_NO_ERROR(gl.getError(), "Could not execute a draw call!");
369 
370 		/* Verify result texture data */
371 		gl.bindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_id);
372 
373 		for (int n_layer = 0; n_layer < m_n_layers && !test_failed; ++n_layer)
374 		{
375 			gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_to_id, 0 /* level */, n_layer);
376 
377 			GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind texture as color attachment to framebuffer!");
378 
379 			if (gl.checkFramebufferStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
380 			{
381 				TCU_FAIL("Read framebuffer is not complete!");
382 			}
383 
384 			gl.memoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
385 
386 			gl.readPixels(0 /* x */, 0 /* y */, m_width, m_height, GL_RGBA_INTEGER, GL_INT, m_layer_data);
387 
388 			GLU_EXPECT_NO_ERROR(gl.getError(),
389 								"Could not read back pixels from the texture bound to color attachment!");
390 
391 			/* Perform the verification */
392 			const int referenceColor[4] = { 0, 255, 0, 0 };
393 
394 			for (int nPx = 0; nPx < m_width * m_height; ++nPx)
395 			{
396 				if (m_layer_data[nPx * m_n_texture_components + 0] != referenceColor[0] ||
397 					m_layer_data[nPx * m_n_texture_components + 1] != referenceColor[1] ||
398 					m_layer_data[nPx * m_n_texture_components + 2] != referenceColor[2] ||
399 					m_layer_data[nPx * m_n_texture_components + 3] != referenceColor[3])
400 				{
401 					m_testCtx.getLog() << tcu::TestLog::Message << "The test failed: Pixel " << nPx << " from layer "
402 									   << n_layer << " is set to [" << m_layer_data[nPx * m_n_texture_components + 0]
403 									   << "," << m_layer_data[nPx * m_n_texture_components + 1] << ","
404 									   << m_layer_data[nPx * m_n_texture_components + 2] << ","
405 									   << m_layer_data[nPx * m_n_texture_components + 3] << "] but should be equal to ["
406 									   << referenceColor[0] << "," << referenceColor[1] << "," << referenceColor[2]
407 									   << "," << referenceColor[3] << ","
408 									   << "]" << tcu::TestLog::EndMessage;
409 
410 					test_failed = true;
411 					break;
412 				} /* if (result pixel is invalid) */
413 			}	 /* for (all pixels) */
414 		}		  /* for (all layers) */
415 
416 		/* Restore the FBO to no-attachment state for the next iteration */
417 		gl.framebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0, 0);
418 
419 	} /* for (both iterations) */
420 
421 	if (test_failed)
422 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
423 	else
424 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
425 
426 	return STOP;
427 }
428 
429 } // namespace glcts
430