• 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 "esextcGeometryShaderOutput.hpp"
25 
26 #include "gluContextInfo.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 
31 namespace glcts
32 {
33 
34 /* Shared shaders */
35 const char* const GeometryShaderOutput::m_fragment_shader_code_white_color = "${VERSION}\n"
36 																			 "\n"
37 																			 "precision highp float;\n"
38 																			 "\n"
39 																			 "out vec4 color;\n"
40 																			 "\n"
41 																			 "void main()\n"
42 																			 "{\n"
43 																			 "    color = vec4(1, 1, 1, 1);\n"
44 																			 "}\n";
45 
46 const char* const GeometryShaderOutput::m_vertex_shader_code_two_vec4 = "${VERSION}\n"
47 																		"\n"
48 																		"precision highp float;\n"
49 																		"\n"
50 																		"out vec4 v1;\n"
51 																		"out vec4 v2;\n"
52 																		"\n"
53 																		"void main()\n"
54 																		"{\n"
55 																		"   v1 = vec4(-0.5, -0.5, 0, 1);\n"
56 																		"   v2 = vec4( 0.5,  0.5, 0, 1);\n"
57 																		"}\n";
58 
59 const char* const GeometryShaderOutput::m_vertex_shader_code_vec4_0_0_0_1 = "${VERSION}\n"
60 																			"\n"
61 																			"precision highp float;\n"
62 																			"\n"
63 																			"void main()\n"
64 																			"{\n"
65 																			"   gl_Position = vec4(0, 0, 0, 1);\n"
66 																			"}\n";
67 
68 /* Shaders for GeometryShaderDuplicateOutputLayoutQualifierTest */
69 const char* const GeometryShaderDuplicateOutputLayoutQualifierTest::m_geometry_shader_code =
70 	"${VERSION}\n"
71 	"\n"
72 	"${GEOMETRY_SHADER_REQUIRE}\n"
73 	"\n"
74 	"layout(points)                            in;\n"
75 	"layout(triangle_strip, max_vertices = 60) out;\n"
76 	"layout(points)                            out;\n"
77 	"\n"
78 	"in vec4 v1[];\n"
79 	"in vec4 v2[];\n"
80 	"\n"
81 	"void main()\n"
82 	"{\n"
83 	"    gl_Position = v1[0] + vec4(-0.1, -0.1, 0, 0);\n"
84 	"    EmitVertex();\n"
85 	"    gl_Position = v1[0] + vec4(0.1, -0.1, 0, 0);\n"
86 	"    EmitVertex();\n"
87 	"    gl_Position = v1[0] + vec4(0.1, 0.1, 0, 0);\n"
88 	"    EmitVertex();\n"
89 	"    EndPrimitive();\n"
90 	"\n"
91 	"    gl_Position = v2[0] + vec4(-0.1, -0.1, 0, 0);\n"
92 	"    EmitVertex();\n"
93 	"    gl_Position = v2[0] + vec4(-0.1, 0.1, 0, 0);\n"
94 	"    EmitVertex();\n"
95 	"    gl_Position = v2[0] + vec4(0.1, 0.1, 0, 0);\n"
96 	"    EmitVertex();\n"
97 	"    EndPrimitive();\n"
98 	"}\n";
99 
100 /* Shaders for GeometryShaderDuplicateMaxVerticesLayoutQualifierTest */
101 const char* const GeometryShaderDuplicateMaxVerticesLayoutQualifierTest::m_geometry_shader_code =
102 	"${VERSION}\n"
103 	"\n"
104 	"${GEOMETRY_SHADER_REQUIRE}\n"
105 	"\n"
106 	"layout(points)                            in;\n"
107 	"layout(triangle_strip, max_vertices = 60) out;\n"
108 	"layout(max_vertices = 20)                 out;\n"
109 	"\n"
110 	"in vec4 v1[];\n"
111 	"in vec4 v2[];\n"
112 	"\n"
113 	"void main()\n"
114 	"{\n"
115 	"    gl_Position = v1[0] + vec4(-0.1, -0.1, 0, 0);\n"
116 	"    EmitVertex();\n"
117 	"    gl_Position = v1[0] + vec4(0.1, -0.1, 0, 0);\n"
118 	"    EmitVertex();\n"
119 	"    gl_Position = v1[0] + vec4(0.1, 0.1, 0, 0);\n"
120 	"    EmitVertex();\n"
121 	"    EndPrimitive();\n"
122 	"\n"
123 	"    gl_Position = v2[0] + vec4(-0.1, -0.1, 0, 0);\n"
124 	"    EmitVertex();\n"
125 	"    gl_Position = v2[0] + vec4(-0.1, 0.1, 0, 0);\n"
126 	"    EmitVertex();\n"
127 	"    gl_Position = v2[0] + vec4(0.1, 0.1, 0, 0);\n"
128 	"    EmitVertex();\n"
129 	"    EndPrimitive();\n"
130 	"}\n";
131 
132 /* Shaders for GeometryShaderIfVertexEmitIsDoneAtEndTest */
133 const char* const GeometryShaderIfVertexEmitIsDoneAtEndTest::m_geometry_shader_code =
134 	"${VERSION}\n"
135 	"\n"
136 	"${GEOMETRY_SHADER_REQUIRE}\n"
137 	"\n"
138 	"precision highp float;\n"
139 	"\n"
140 	"layout(points)                            in;\n"
141 	"layout(triangle_strip, max_vertices = 60) out;\n"
142 	"\n"
143 	"in vec4 v1[];\n"
144 	"\n"
145 	"void main()\n"
146 	"{\n"
147 	"    gl_Position = vec4(-1, -1, 0, 1);\n"
148 	"    EmitVertex();\n"
149 	"    gl_Position = vec4(-1, 1, 0, 1);\n"
150 	"    EmitVertex();\n"
151 	"    gl_Position = vec4(1, 1, 0, 1);\n"
152 	"    EndPrimitive();\n"
153 	"}\n";
154 
155 /* Shaders for GeometryShaderMissingEndPrimitiveCallTest */
156 const char* const GeometryShaderMissingEndPrimitiveCallTest::m_geometry_shader_code =
157 	"${VERSION}\n"
158 	"\n"
159 	"${GEOMETRY_SHADER_REQUIRE}\n"
160 	"\n"
161 	"layout(points)                            in;\n"
162 	"layout(triangle_strip, max_vertices = 60) out;\n"
163 	"\n"
164 	"void main()\n"
165 	"{\n"
166 	"    gl_Position = vec4(-1, -1.004, 0, 1);\n"
167 	"    EmitVertex();\n"
168 	"    gl_Position = vec4(-1, 1, 0, 1);\n"
169 	"    EmitVertex();\n"
170 	"    gl_Position = vec4(1.004, 1, 0, 1);\n"
171 	"    EmitVertex();\n"
172 	"}\n";
173 
174 /* Shaders for GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest */
175 const char* const GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest::m_geometry_shader_code =
176 	"${VERSION}\n"
177 	"\n"
178 	"${GEOMETRY_SHADER_REQUIRE}\n"
179 	"${GEOMETRY_POINT_SIZE_ENABLE}\n"
180 	"\n"
181 	"layout(points)                   in;\n"
182 	"layout(points, max_vertices = 1) out;\n"
183 	"\n"
184 	"void main()\n"
185 	"{\n"
186 	"    gl_Position  = vec4(-1, -1, 0, 1);\n"
187 	"    gl_PointSize = 2.0f;\n"
188 	"    EmitVertex();\n"
189 	"}\n";
190 
191 /* Definitions used by all test cases */
192 #define TEXTURE_HEIGHT (16)
193 #define TEXTURE_PIXEL_SIZE (4)
194 #define TEXTURE_WIDTH (16)
195 
196 /** Constructor
197  *
198  *  @param context       Test context
199  *  @param name          Test case's name
200  *  @param description   Test case's description
201  **/
GeometryShaderOutput(Context & context,const ExtParameters & extParams,const char * name,const char * description)202 GeometryShaderOutput::GeometryShaderOutput(Context& context, const ExtParameters& extParams, const char* name,
203 										   const char* description)
204 	: TestCaseBase(context, extParams, name, description)
205 {
206 	/* Left blank on purpose */
207 }
208 
209 /** Constructor
210  *
211  *  @param context       Test context
212  *  @param name          Test case's name
213  *  @param description   Test case's desricption
214  **/
GeometryShaderDuplicateOutputLayoutQualifierTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)215 GeometryShaderDuplicateOutputLayoutQualifierTest::GeometryShaderDuplicateOutputLayoutQualifierTest(
216 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
217 	: GeometryShaderOutput(context, extParams, name, description)
218 {
219 	/* Nothing to be done here */
220 }
221 
222 /** Executes the test.
223  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
224  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
225  *  Note the function throws exception should an error occur!
226  **/
iterate()227 tcu::TestCase::IterateResult GeometryShaderDuplicateOutputLayoutQualifierTest::iterate()
228 {
229 	if (!m_is_geometry_shader_extension_supported)
230 	{
231 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
232 	}
233 
234 	/* Verify the program does not build. */
235 	bool result = doesProgramBuild(1, &m_fragment_shader_code_white_color, 1, &m_geometry_shader_code, 1,
236 								   &m_vertex_shader_code_two_vec4);
237 
238 	if (false == result)
239 	{
240 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
241 	}
242 	else
243 	{
244 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid program was linked successfully."
245 						   << tcu::TestLog::EndMessage;
246 
247 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
248 	}
249 
250 	return STOP;
251 }
252 
253 /** Constructor
254  *
255  *  @param context       Test context
256  *  @param name          Test case's name
257  *  @param description   Test case's desricption
258  **/
GeometryShaderDuplicateMaxVerticesLayoutQualifierTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)259 GeometryShaderDuplicateMaxVerticesLayoutQualifierTest::GeometryShaderDuplicateMaxVerticesLayoutQualifierTest(
260 	Context& context, const ExtParameters& extParams, const char* name, const char* description)
261 	: GeometryShaderOutput(context, extParams, name, description)
262 {
263 	/* Nothing to be done here */
264 }
265 
266 /** Executes the test.
267  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
268  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
269  *  Note the function throws exception should an error occur!
270  **/
iterate()271 tcu::TestCase::IterateResult GeometryShaderDuplicateMaxVerticesLayoutQualifierTest::iterate()
272 {
273 	if (!m_is_geometry_shader_extension_supported)
274 	{
275 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
276 	}
277 
278 	/* Verify the program does not build. */
279 	bool result = doesProgramBuild(1, &m_fragment_shader_code_white_color, 1, &m_geometry_shader_code, 1,
280 								   &m_vertex_shader_code_two_vec4);
281 
282 	if (false == result)
283 	{
284 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
285 	}
286 	else
287 	{
288 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid program was linked successfully."
289 						   << tcu::TestLog::EndMessage;
290 
291 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
292 	}
293 
294 	return STOP;
295 }
296 
297 /** Constructor
298  *
299  *  @param context                  Test context
300  *  @param name                     Test case's name
301  *  @param description              Test case's desricption
302  *  @param geometry_shader_code     Code of geometry shader
303  **/
GeometryShaderOutputRenderingBase(Context & context,const ExtParameters & extParams,const char * name,const char * description,const char * geometry_shader_code)304 GeometryShaderOutputRenderingBase::GeometryShaderOutputRenderingBase(Context& context, const ExtParameters& extParams,
305 																	 const char* name, const char* description,
306 																	 const char* geometry_shader_code)
307 	: GeometryShaderOutput(context, extParams, name, description)
308 	, m_geometry_shader_code(geometry_shader_code)
309 	, m_program_object_id(0)
310 	, m_vertex_shader_id(0)
311 	, m_fragment_shader_id(0)
312 	, m_geometry_shader_id(0)
313 	, m_vao_id(0)
314 	, m_fbo_id(0)
315 	, m_color_tex_id(0)
316 {
317 	/* Left blank on purpose */
318 }
319 
320 /** Initialize test case
321  *
322  **/
initTest()323 void GeometryShaderOutputRenderingBase::initTest()
324 {
325 	if (!m_is_geometry_shader_extension_supported)
326 	{
327 		throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
328 	}
329 
330 	/* GL functions */
331 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
332 
333 	/* Create shader objects */
334 	m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
335 	m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
336 	m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);
337 
338 	/* Create program object */
339 	m_program_object_id = gl.createProgram();
340 
341 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object");
342 
343 	/* Build the program object */
344 	if (false == buildProgram(m_program_object_id, m_fragment_shader_id, 1, &m_fragment_shader_code_white_color,
345 							  m_geometry_shader_id, 1, &m_geometry_shader_code, m_vertex_shader_id, 1,
346 							  &m_vertex_shader_code_vec4_0_0_0_1))
347 	{
348 		TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
349 	}
350 
351 	/* Set up texture object and a FBO */
352 	gl.genTextures(1, &m_color_tex_id);
353 	gl.genFramebuffers(1, &m_fbo_id);
354 
355 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create framebuffer");
356 
357 	if (false ==
358 		setupFramebufferWithTextureAsAttachment(m_fbo_id, m_color_tex_id, GL_RGBA8, TEXTURE_WIDTH, TEXTURE_HEIGHT))
359 	{
360 		TCU_FAIL("Failed to setup framebuffer");
361 	}
362 
363 	/* Set up a vertex array object */
364 	gl.genVertexArrays(1, &m_vao_id);
365 	gl.bindVertexArray(m_vao_id);
366 
367 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
368 	{
369 		gl.enable(GL_PROGRAM_POINT_SIZE);
370 	}
371 
372 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create vertex array object");
373 }
374 
375 /** Executes the test.
376  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
377  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
378  *  Note the function throws exception should an error occur!
379  **/
iterate()380 tcu::TestCase::IterateResult GeometryShaderOutputRenderingBase::iterate()
381 {
382 	initTest();
383 
384 	/* Variables used for image verification purposes */
385 	unsigned char result_image[TEXTURE_HEIGHT * TEXTURE_WIDTH * TEXTURE_PIXEL_SIZE];
386 
387 	/* GL functions */
388 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
389 
390 	/* Render */
391 	gl.useProgram(m_program_object_id);
392 
393 	gl.clearColor(0 /* red */, 0 /* green */, 0 /* blue */, 0 /* alpha */);
394 	gl.clear(GL_COLOR_BUFFER_BIT);
395 
396 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not clear the color buffer");
397 
398 	gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
399 
400 	GLU_EXPECT_NO_ERROR(gl.getError(), "Call drawArrays() failed");
401 
402 	/* Extract image from FBO */
403 	gl.readPixels(0 /* x */, 0 /* y */, TEXTURE_WIDTH, TEXTURE_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, result_image);
404 
405 	GLU_EXPECT_NO_ERROR(gl.getError(), "Could not read back pixels from color buffer");
406 
407 	/* Run verification */
408 	if (true == verifyResult(result_image, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_PIXEL_SIZE))
409 	{
410 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
411 	}
412 	else
413 	{
414 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
415 	}
416 
417 	return STOP;
418 }
419 
420 /** Deinitialize test case
421  *
422  **/
deinit()423 void GeometryShaderOutputRenderingBase::deinit()
424 {
425 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
426 
427 	/* Reset OpenGL ES state */
428 	gl.useProgram(0);
429 	gl.bindVertexArray(0);
430 	gl.bindTexture(GL_TEXTURE_2D, 0);
431 	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
432 	if (!glu::isContextTypeES(m_context.getRenderContext().getType()))
433 	{
434 		gl.disable(GL_PROGRAM_POINT_SIZE);
435 	}
436 
437 	if (m_program_object_id != 0)
438 	{
439 		gl.deleteProgram(m_program_object_id);
440 	}
441 
442 	if (m_fragment_shader_id != 0)
443 	{
444 		gl.deleteShader(m_fragment_shader_id);
445 	}
446 
447 	if (m_geometry_shader_id != 0)
448 	{
449 		gl.deleteShader(m_geometry_shader_id);
450 	}
451 
452 	if (m_vertex_shader_id != 0)
453 	{
454 		gl.deleteShader(m_vertex_shader_id);
455 	}
456 
457 	if (m_vao_id != 0)
458 	{
459 		gl.deleteVertexArrays(1, &m_vao_id);
460 	}
461 
462 	if (m_color_tex_id != 0)
463 	{
464 		gl.deleteTextures(1, &m_color_tex_id);
465 	}
466 
467 	if (m_fbo_id != 0)
468 	{
469 		gl.deleteFramebuffers(1, &m_fbo_id);
470 	}
471 
472 	/* Release base class */
473 	TestCaseBase::deinit();
474 }
475 
476 /** Constructor
477  *
478  *  @param context       Test context
479  *  @param name          Test case's name
480  *  @param description   Test case's desricption
481  **/
GeometryShaderIfVertexEmitIsDoneAtEndTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)482 GeometryShaderIfVertexEmitIsDoneAtEndTest::GeometryShaderIfVertexEmitIsDoneAtEndTest(Context&			  context,
483 																					 const ExtParameters& extParams,
484 																					 const char*		  name,
485 																					 const char*		  description)
486 	: GeometryShaderOutputRenderingBase(context, extParams, name, description, m_geometry_shader_code)
487 {
488 	/* Left blank on purpose */
489 }
490 
491 /** Verifies result of draw call
492  *
493  *  @param result_image Image data
494  *  @param width        Image width
495  *  @param height       Image height
496  *  @param pixel_size   Size of single pixel in bytes
497  *
498  *  @return true  if test succeded
499  *          false if the test failed
500  *          Note the function throws exception should an error occur!
501  **/
verifyResult(const unsigned char * result_image,unsigned int width,unsigned int height,unsigned int pixel_size) const502 bool GeometryShaderIfVertexEmitIsDoneAtEndTest::verifyResult(const unsigned char* result_image, unsigned int width,
503 															 unsigned int height, unsigned int pixel_size) const
504 {
505 	/* Check if the data was modified during the rendering process */
506 	for (unsigned int y = 0; y < height; ++y)
507 	{
508 		for (unsigned int x = 0; x < width; ++x)
509 		{
510 			if (false == comparePixel(result_image, x, y, width, height, pixel_size))
511 			{
512 				m_testCtx.getLog() << tcu::TestLog::Message
513 								   << "Vertex emitted without a corresponding EmitVertex() call made"
514 								   << tcu::TestLog::EndMessage;
515 
516 				return false;
517 			}
518 		}
519 	}
520 
521 	/* Done */
522 	return true;
523 }
524 
525 /** Constructor
526  *
527  *  @param context       Test context
528  *  @param name          Test case's name
529  *  @param description   Test case's desricption
530  **/
GeometryShaderMissingEndPrimitiveCallTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)531 GeometryShaderMissingEndPrimitiveCallTest::GeometryShaderMissingEndPrimitiveCallTest(Context&			  context,
532 																					 const ExtParameters& extParams,
533 																					 const char*		  name,
534 																					 const char*		  description)
535 	: GeometryShaderOutputRenderingBase(context, extParams, name, description, m_geometry_shader_code)
536 {
537 	/* Left blank on purpose */
538 }
539 
540 /** Verifies result of draw call
541  *
542  *  @param result_image Image data
543  *  @param width        Image width
544  *  @param height       Image height
545  *  @param pixel_size   Size of single pixel in bytes
546  *
547  *  @return true  if test succeded
548  *          false if the test failed
549  **/
verifyResult(const unsigned char * result_image,unsigned int width,unsigned int height,unsigned int pixel_size) const550 bool GeometryShaderMissingEndPrimitiveCallTest::verifyResult(const unsigned char* result_image, unsigned int width,
551 															 unsigned int height, unsigned int pixel_size) const
552 {
553 	/* Image size */
554 	const unsigned int left   = 0;
555 	const unsigned int right  = width - 1;
556 	const unsigned int bottom = 0;
557 	const unsigned int top	= height - 1;
558 
559 	/* Verification */
560 	if ((true == comparePixel(result_image, left, bottom, width, height, pixel_size, 255, 255, 255, 255)) &&
561 		(true == comparePixel(result_image, left, top, width, height, pixel_size, 255, 255, 255, 255)) &&
562 		(true == comparePixel(result_image, right, top, width, height, pixel_size, 255, 255, 255, 255)) &&
563 		(true == comparePixel(result_image, right, bottom, width, height, pixel_size, 0, 0, 0, 0)))
564 	{
565 		return true;
566 	}
567 	else
568 	{
569 		m_testCtx.getLog() << tcu::TestLog::Message << "EndPrimitive() is not called at the end of geometry shader"
570 						   << tcu::TestLog::EndMessage;
571 
572 		return false;
573 	}
574 }
575 
576 /** Constructor
577  *
578  *  @param context       Test context
579  *  @param name          Test case's name
580  *  @param description   Test case's desricption
581  **/
582 GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest::
GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)583 	GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest(Context& context, const ExtParameters& extParams,
584 																const char* name, const char* description)
585 	: GeometryShaderOutputRenderingBase(context, extParams, name, description, m_geometry_shader_code)
586 {
587 	/* Left blank on purpose */
588 }
589 
590 /** Executes the test.
591  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
592  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
593  *  Note the function throws exception should an error occur!
594  **/
iterate()595 tcu::TestCase::IterateResult GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest::iterate()
596 {
597 	if (!m_is_geometry_shader_point_size_supported)
598 	{
599 		throw tcu::NotSupportedError(GEOMETRY_SHADER_POINT_SIZE_NOT_SUPPORTED, "", __FILE__, __LINE__);
600 	}
601 
602 	return GeometryShaderOutputRenderingBase::iterate();
603 }
604 
605 /** Verifies result of draw call
606  *
607  *  @param result_image Image data
608  *  @param width        Image width
609  *  @param height       Image height
610  *  @param pixel_size   Size of single pixel in bytes
611  *
612  *  @return true  if test succeded
613  *          false if the test failed
614  *          Note the function throws exception should an error occur!
615  **/
verifyResult(const unsigned char * result_image,unsigned int width,unsigned int height,unsigned int pixel_size) const616 bool GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest::verifyResult(const unsigned char* result_image,
617 																			   unsigned int width, unsigned int height,
618 																			   unsigned int pixel_size) const
619 {
620 	/* Image size */
621 	const unsigned int left   = 0;
622 	const unsigned int right  = width - 1;
623 	const unsigned int bottom = 0;
624 	const unsigned int top	= height - 1;
625 
626 	/* Verification */
627 	if ((true == comparePixel(result_image, left, bottom, width, height, pixel_size, 255, 255, 255, 255)) &&
628 		(true == comparePixel(result_image, left, top, width, height, pixel_size, 0, 0, 0, 0)) &&
629 		(true == comparePixel(result_image, right, top, width, height, pixel_size, 0, 0, 0, 0)) &&
630 		(true == comparePixel(result_image, right, bottom, width, height, pixel_size, 0, 0, 0, 0)))
631 	{
632 		return true;
633 	}
634 	else
635 	{
636 		m_testCtx.getLog() << tcu::TestLog::Message << "EndPrimitive() is not done for a single primitive"
637 						   << tcu::TestLog::EndMessage;
638 
639 		return false;
640 	}
641 }
642 
643 } // namespace glcts
644