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