1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2015-2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 */ /*-------------------------------------------------------------------*/
23 #include "esextcGeometryShaderAPI.hpp"
25 #include "gluDefs.hpp"
26 #include "glwEnums.hpp"
27 #include "glwFunctions.hpp"
28 #include "tcuTestLog.hpp"
34 static const char* dummy_fs_code = "${VERSION}\n"
36 "precision highp float;\n"
42 " result = vec4(1.0);\n"
45 static const char* dummy_gs_code = "${VERSION}\n"
46 "${GEOMETRY_SHADER_REQUIRE}\n"
48 "layout (points) in;\n"
49 "layout (points, max_vertices = 1) out;\n"
51 "${OUT_PER_VERTEX_DECL}"
55 "${POSITION_WITH_IN_DATA}"
59 static const char* dummy_vs_code = "${VERSION}\n"
61 "${OUT_PER_VERTEX_DECL}"
65 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
68 /* createShaderProgramv conformance test shaders */
69 const char* GeometryShaderCreateShaderProgramvTest::fs_code = "${VERSION}\n"
71 "precision highp float;\n"
77 " result = vec4(0.0, 1.0, 0.0, 0.0);\n"
80 const char* GeometryShaderCreateShaderProgramvTest::gs_code = "${VERSION}\n"
81 "${GEOMETRY_SHADER_REQUIRE}\n"
83 "layout (points) in;\n"
84 "layout (triangle_strip, max_vertices = 4) out;\n"
86 "${OUT_PER_VERTEX_DECL}"
90 " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n"
93 " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n"
96 " gl_Position = vec4(1.0, -1.0, 0.0, 1.0);\n"
99 " gl_Position = vec4(1.0, 1.0, 0.0, 1.0);\n"
104 const char* GeometryShaderCreateShaderProgramvTest::vs_code = "${VERSION}\n"
106 "${OUT_PER_VERTEX_DECL}"
110 " gl_Position = vec4(-10.0, -10.0, -10.0, 0.0);\n"
113 const unsigned int GeometryShaderCreateShaderProgramvTest::m_to_height = 4;
114 const unsigned int GeometryShaderCreateShaderProgramvTest::m_to_width = 4;
118 * @param context Test context
119 * @param extParams Not used.
120 * @param name Test case's name
121 * @param description Test case's description
123 GeometryShaderCreateShaderProgramvTest::GeometryShaderCreateShaderProgramvTest(Context& context,
124 const ExtParameters& extParams,
126 const char* description)
127 : TestCaseBase(context, extParams, name, description)
131 , m_pipeline_object_id(0)
138 /** Deinitializes GLES objects created during the test. */
139 void GeometryShaderCreateShaderProgramvTest::deinit()
141 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
145 gl.deleteFramebuffers(1, &m_fbo_id);
152 gl.deleteProgram(m_fs_po_id);
159 gl.deleteProgram(m_gs_po_id);
164 if (m_pipeline_object_id != 0)
166 gl.deleteProgramPipelines(1, &m_pipeline_object_id);
168 m_pipeline_object_id = 0;
173 gl.deleteTextures(1, &m_to_id);
180 gl.deleteVertexArrays(1, &m_vao_id);
187 gl.deleteProgram(m_vs_po_id);
192 /* Release base class */
193 TestCaseBase::deinit();
196 /** Initializes a framebuffer object used by the conformance test. */
197 void GeometryShaderCreateShaderProgramvTest::initFBO()
199 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
202 gl.genFramebuffers(1, &m_fbo_id);
203 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
206 gl.genTextures(1, &m_to_id);
207 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
210 gl.bindTexture(GL_TEXTURE_2D, m_to_id);
211 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
213 gl.texStorage2D(GL_TEXTURE_2D, 1, /* levels */
214 GL_RGBA8, m_to_width, m_to_height);
215 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
218 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
219 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
221 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_to_id, 0); /* level */
222 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
224 /* Set up the viewport */
225 gl.viewport(0, /* x */
227 m_to_width, m_to_height);
229 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport() call failed.");
232 /* Initializes a pipeline object used by the conformance test */
233 void GeometryShaderCreateShaderProgramvTest::initPipelineObject()
235 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
237 DE_ASSERT(m_fs_po_id != 0 && m_gs_po_id != 0 && m_vs_po_id != 0);
239 gl.genProgramPipelines(1, &m_pipeline_object_id);
240 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
242 gl.useProgramStages(m_pipeline_object_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id);
243 gl.useProgramStages(m_pipeline_object_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id);
244 gl.useProgramStages(m_pipeline_object_id, GL_VERTEX_SHADER_BIT, m_vs_po_id);
246 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed.");
249 /** Executes the test.
251 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
252 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
253 * Note the function throws exception should an error occur!
255 tcu::TestNode::IterateResult GeometryShaderCreateShaderProgramvTest::iterate()
257 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
258 const unsigned int n_so_po_ids = 3;
260 glw::GLuint so_po_ids[n_so_po_ids];
262 /* This test should only run if EXT_geometry_shader is supported. */
263 if (!m_is_geometry_shader_extension_supported)
265 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
268 /* Initialize off-screen rendering */
271 /* Form shader sources */
272 std::string fs_specialized_code = specializeShader(1,
273 /* parts */ &fs_code);
274 const char* fs_specialized_code_raw = fs_specialized_code.c_str();
275 std::string gs_specialized_code = specializeShader(1,
276 /* parts */ &gs_code);
277 const char* gs_specialized_code_raw = gs_specialized_code.c_str();
278 std::string vs_specialized_code = specializeShader(1,
279 /* parts */ &vs_code);
280 const char* vs_specialized_code_raw = vs_specialized_code.c_str();
282 /* Try to create an invalid geometry shader program first */
283 glw::GLint link_status = GL_TRUE;
285 m_gs_po_id = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1, /* count */
288 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
292 m_testCtx.getLog() << tcu::TestLog::Message << "glCreateShaderProgramv() call returned 0."
293 << tcu::TestLog::EndMessage;
299 gl.getProgramiv(m_gs_po_id, GL_LINK_STATUS, &link_status);
300 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
302 if (link_status != GL_FALSE)
304 m_testCtx.getLog() << tcu::TestLog::Message << "An invalid shader program was linked successfully."
305 << tcu::TestLog::EndMessage;
311 gl.deleteProgram(m_gs_po_id);
312 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram() call failed.");
314 /* Create shader programs */
315 m_fs_po_id = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, /* count */
316 &fs_specialized_code_raw);
317 m_gs_po_id = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1, /* count */
318 &gs_specialized_code_raw);
319 m_vs_po_id = gl.createShaderProgramv(GL_VERTEX_SHADER, 1, /* count */
320 &vs_specialized_code_raw);
322 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call(s) failed.");
324 if (m_fs_po_id == 0 || m_gs_po_id == 0 || m_vs_po_id == 0)
326 m_testCtx.getLog() << tcu::TestLog::Message << "At least one glCreateShaderProgramv() call returned 0."
327 << tcu::TestLog::EndMessage;
333 /* Make sure all shader programs were linked successfully */
334 so_po_ids[0] = m_fs_po_id;
335 so_po_ids[1] = m_gs_po_id;
336 so_po_ids[2] = m_vs_po_id;
338 for (unsigned int n_po_id = 0; n_po_id != n_so_po_ids; ++n_po_id)
340 gl.getProgramiv(so_po_ids[n_po_id], GL_LINK_STATUS, &link_status);
341 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
343 if (link_status != GL_TRUE)
345 m_testCtx.getLog() << tcu::TestLog::Message << "A valid shader program with id [" << so_po_ids[n_po_id]
346 << "] was not linked successfully." << tcu::TestLog::EndMessage;
353 /* Set up the vertex array object */
354 gl.genVertexArrays(1, &m_vao_id);
355 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
357 gl.bindVertexArray(m_vao_id);
358 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
360 /* Set up the pipeline object */
361 initPipelineObject();
363 /* Render a full-screen quad */
364 gl.bindProgramPipeline(m_pipeline_object_id);
365 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
367 gl.drawArrays(GL_POINTS, 0, /* first */
369 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
371 /* Verify the rendering result */
372 unsigned char result_data[m_to_width * m_to_height * 4 /* rgba */];
374 gl.readPixels(0, /* x */
376 m_to_width, m_to_height, GL_RGBA, GL_UNSIGNED_BYTE, result_data);
377 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
379 for (unsigned int y = 0; y < m_to_height; ++y)
381 unsigned char* traveller_ptr = result_data + 4 * y;
383 for (unsigned int x = 0; x < m_to_width; ++x)
385 if (traveller_ptr[0] != 0 || traveller_ptr[1] != 255 || traveller_ptr[2] != 0 || traveller_ptr[3] != 0)
387 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid result texel found at (" << x << ", " << y
388 << ")." << tcu::TestLog::EndMessage;
393 traveller_ptr += 4; /* rgba */
400 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
404 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
412 * @param context Test context
413 * @param extParams Not used.
414 * @param name Test case's name
415 * @param description Test case's description
417 GeometryShaderGetShaderivTest::GeometryShaderGetShaderivTest(Context& context, const ExtParameters& extParams,
418 const char* name, const char* description)
419 : TestCaseBase(context, extParams, name, description), m_gs_id(0)
423 /** Deinitializes GLES objects created during the test. */
424 void GeometryShaderGetShaderivTest::deinit()
426 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
430 gl.deleteShader(m_gs_id);
435 /* Release base class */
436 TestCaseBase::deinit();
439 /** Executes the test.
441 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
442 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
443 * Note the function throws exception should an error occur!
445 tcu::TestNode::IterateResult GeometryShaderGetShaderivTest::iterate()
447 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
450 /* This test should only run if EXT_geometry_shader is supported. */
451 if (!m_is_geometry_shader_extension_supported)
453 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
457 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
459 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
461 /* Check the type reported for the SO */
462 glw::GLint shader_type = GL_NONE;
464 gl.getShaderiv(m_gs_id, GL_SHADER_TYPE, &shader_type);
465 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
467 if ((glw::GLenum)shader_type != m_glExtTokens.GEOMETRY_SHADER)
469 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid shader type [" << shader_type
470 << "] reported for a Geometry Shader" << tcu::TestLog::EndMessage;
477 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
481 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
489 * @param context Test context
490 * @param extParams Not used.
491 * @param name Test case's name
492 * @param description Test case's description
494 GeometryShaderGetProgramivTest::GeometryShaderGetProgramivTest(Context& context, const ExtParameters& extParams,
495 const char* name, const char* description)
496 : TestCaseBase(context, extParams, name, description), m_po_id(0)
500 /** Deinitializes GLES objects created during the test. */
501 void GeometryShaderGetProgramivTest::deinit()
503 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
507 gl.deleteProgram(m_po_id);
512 /* Release base class */
513 TestCaseBase::deinit();
516 /** Executes the test.
518 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
519 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
520 * Note the function throws exception should an error occur!
522 tcu::TestNode::IterateResult GeometryShaderGetProgramivTest::iterate()
524 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
527 /* This test should only run if EXT_geometry_shader is supported. */
528 if (!m_is_geometry_shader_extension_supported)
530 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
533 /* Create a program object */
534 m_po_id = gl.createProgram();
536 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
538 /* Verify that GS-specific queries cause a GL_INVALID_OPERATION error */
539 const glw::GLenum pnames[] = { m_glExtTokens.GEOMETRY_LINKED_VERTICES_OUT, m_glExtTokens.GEOMETRY_LINKED_INPUT_TYPE,
540 m_glExtTokens.GEOMETRY_LINKED_OUTPUT_TYPE,
541 m_glExtTokens.GEOMETRY_SHADER_INVOCATIONS };
542 const unsigned int n_pnames = sizeof(pnames) / sizeof(pnames[0]);
544 for (unsigned int n_pname = 0; n_pname < n_pnames; ++n_pname)
546 glw::GLenum error_code = GL_NO_ERROR;
547 glw::GLenum pname = pnames[n_pname];
550 gl.getProgramiv(m_po_id, pname, &rv);
552 error_code = gl.getError();
554 if (error_code != GL_INVALID_OPERATION)
556 m_testCtx.getLog() << tcu::TestLog::Message << "No error generated by glGetProgramiv() for pname [" << pname
557 << "]" << tcu::TestLog::EndMessage;
561 } /* for (all pnames) */
565 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
569 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
577 * @param context Test context
578 * @param extParams Not used.
579 * @param name Test case's name
580 * @param description Test case's description
582 GeometryShaderGetProgramiv2Test::GeometryShaderGetProgramiv2Test(Context& context, const ExtParameters& extParams,
583 const char* name, const char* description)
584 : TestCaseBase(context, extParams, name, description), m_fs_id(0), m_po_id(0), m_vs_id(0)
588 /** Deinitializes GLES objects created during the test. */
589 void GeometryShaderGetProgramiv2Test::deinit()
591 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
595 gl.deleteShader(m_fs_id);
602 gl.deleteProgram(m_po_id);
609 gl.deleteShader(m_vs_id);
614 /* Release base class */
615 TestCaseBase::deinit();
618 /** Executes the test.
620 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
621 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
622 * Note the function throws exception should an error occur!
624 tcu::TestNode::IterateResult GeometryShaderGetProgramiv2Test::iterate()
626 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
627 const glw::GLenum pnames[] = { m_glExtTokens.GEOMETRY_LINKED_VERTICES_OUT, m_glExtTokens.GEOMETRY_LINKED_INPUT_TYPE,
628 m_glExtTokens.GEOMETRY_LINKED_OUTPUT_TYPE,
629 m_glExtTokens.GEOMETRY_SHADER_INVOCATIONS };
630 const unsigned int n_pnames = sizeof(pnames) / sizeof(pnames[0]);
633 /* This test should only run if EXT_geometry_shader is supported. */
634 if (!m_is_geometry_shader_extension_supported)
636 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
639 /* Initialize the program object */
640 std::string specialized_dummy_fs = specializeShader(1,
641 /* parts */ &dummy_fs_code);
642 const char* specialized_dummy_fs_raw = specialized_dummy_fs.c_str();
643 std::string specialized_dummy_vs = specializeShader(1,
644 /* parts */ &dummy_vs_code);
645 const char* specialized_dummy_vs_raw = specialized_dummy_vs.c_str();
647 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
648 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
650 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
652 m_po_id = gl.createProgram();
654 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
656 if (!TestCaseBase::buildProgram(m_po_id, m_fs_id, 1, &specialized_dummy_fs_raw, m_vs_id, 1,
657 &specialized_dummy_vs_raw))
659 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to build a dummy test program object"
660 << tcu::TestLog::EndMessage;
666 /* Verify that GS-specific queries cause a GL_INVALID_OPERATION error
667 * for a linked PO lacking the GS stage.
669 for (unsigned int n_pname = 0; n_pname < n_pnames; ++n_pname)
671 glw::GLenum error_code = GL_NO_ERROR;
672 glw::GLenum pname = pnames[n_pname];
675 gl.getProgramiv(m_po_id, pname, &rv);
677 error_code = gl.getError();
679 if (error_code != GL_INVALID_OPERATION)
681 m_testCtx.getLog() << tcu::TestLog::Message << "No error generated by glGetProgramiv() for pname [" << pname
682 << "]" << tcu::TestLog::EndMessage;
686 } /* for (all pnames) */
691 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
695 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
703 * @param context Test context
704 * @param extParams Not used.
705 * @param name Test case's name
706 * @param description Test case's description
708 GeometryShaderGetProgramiv3Test::GeometryShaderGetProgramiv3Test(Context& context, const ExtParameters& extParams,
709 const char* name, const char* description)
710 : TestCaseBase(context, extParams, name, description)
715 , m_pipeline_object_id(0)
722 /* Compiles a shader object using caller-specified data.
724 * @param so_id ID of a Shader Object to compile.
725 * @param so_body Body to use for the compilation process.
727 * @return true if the compilation succeeded, false otherwise */
728 bool GeometryShaderGetProgramiv3Test::buildShader(glw::GLuint so_id, const char* so_body)
730 glw::GLint compile_status = GL_FALSE;
731 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
734 gl.shaderSource(so_id, 1, /* count */
735 &so_body, DE_NULL); /* length */
736 GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
738 gl.compileShader(so_id);
739 GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
741 gl.getShaderiv(so_id, GL_COMPILE_STATUS, &compile_status);
742 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
744 result = (compile_status == GL_TRUE);
749 /** Builds a single shader program object using caller-specified data.
751 * @param out_spo_id Deref will be set to the ID of the created shader program object.
753 * @param spo_bits Bits to be passed to the glCreateShaderProgramv() call.
754 * @param spo_body Body to use for the glCreateShaderProgramv() call.
756 * @return true if the shader program object was linked successfully, false otherwise.
758 bool GeometryShaderGetProgramiv3Test::buildShaderProgram(glw::GLuint* out_spo_id, glw::GLenum spo_bits,
759 const char* spo_body)
761 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
762 glw::GLint link_status = GL_FALSE;
765 *out_spo_id = gl.createShaderProgramv(spo_bits, 1, /* count */
768 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call failed.");
770 gl.getProgramiv(*out_spo_id, GL_LINK_STATUS, &link_status);
771 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
773 result = (link_status == GL_TRUE);
778 /** Deinitializes GLES objects created during the test. */
779 void GeometryShaderGetProgramiv3Test::deinit()
781 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
787 if (m_pipeline_object_id != 0)
789 gl.deleteProgramPipelines(1, &m_pipeline_object_id);
791 m_pipeline_object_id = 0;
794 /* Release base class */
795 TestCaseBase::deinit();
798 /** Deinitializes a program object created for the conformance test. */
799 void GeometryShaderGetProgramiv3Test::deinitPO()
801 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
805 gl.deleteProgram(m_po_id);
811 /** Deinitializes shader objects created for the conformance test. */
812 void GeometryShaderGetProgramiv3Test::deinitSOs(bool release_all_SOs)
814 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
816 if (m_fs_id != 0 && release_all_SOs)
818 gl.deleteShader(m_fs_id);
825 gl.deleteShader(m_gs_id);
830 if (m_vs_id != 0 && release_all_SOs)
832 gl.deleteShader(m_vs_id);
838 /** Deinitializes shader program objects created for the conformance test. */
839 void GeometryShaderGetProgramiv3Test::deinitSPOs(bool release_all_SPOs)
841 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
843 if (m_fs_po_id != 0 && release_all_SPOs)
845 gl.deleteProgram(m_fs_po_id);
852 gl.deleteProgram(m_gs_po_id);
857 if (m_vs_po_id != 0 && release_all_SPOs)
859 gl.deleteProgram(m_vs_po_id);
865 /** Retrieves ES SL layout qualifier, corresponding to user-specified
868 * @param primitive_type Primitive type (described by a GLenum value)
869 * to use for the query.
871 * @return Requested layout qualifier.
873 std::string GeometryShaderGetProgramiv3Test::getLayoutQualifierForPrimitiveType(glw::GLenum primitive_type)
877 switch (primitive_type)
880 result = "line_strip";
882 case GL_LINES_ADJACENCY:
883 result = "lines_adjacency";
889 result = "triangles";
891 case GL_TRIANGLE_STRIP:
892 result = "triangle_strip";
899 } /* switch (primitive_type) */
904 /** Retrieves body of a geometry shadet to be used for the conformance test.
905 * The body is generated, according to the properties described by the
906 * run descriptor passed as an argument.
908 * @param run Test run descriptor.
910 * @return Requested string.
912 std::string GeometryShaderGetProgramiv3Test::getGSCode(const _run& run)
914 std::stringstream code_sstream;
916 code_sstream << "${VERSION}\n"
917 "${GEOMETRY_SHADER_REQUIRE}\n"
920 << getLayoutQualifierForPrimitiveType(run.input_primitive_type) << ", "
922 << run.invocations << ") in;\n"
924 << getLayoutQualifierForPrimitiveType(run.output_primitive_type) << ", "
926 << run.max_vertices << ") out;\n"
928 "out gl_PerVertex {\n"
929 " vec4 gl_Position;\n"
934 " for (int n = 0; n < "
935 << run.max_vertices << "; ++n)\n"
937 " gl_Position = vec4(n, 0.0, 0.0, 1.0);\n"
944 return code_sstream.str();
947 /** Initializes internal _runs member with test iteration settings for all test runs. */
948 void GeometryShaderGetProgramiv3Test::initTestRuns()
950 /* input primitive type | invocations | max vertices | output primitive type *
951 *----------------------------------------+-------------+--------------+-----------------------*/
952 _runs.push_back(_run(GL_LINES_ADJACENCY, 3, 16, GL_POINTS));
953 _runs.push_back(_run(GL_TRIANGLES, 12, 37, GL_LINE_STRIP));
954 _runs.push_back(_run(GL_POINTS, 31, 75, GL_TRIANGLE_STRIP));
957 /** Executes the test.
959 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
960 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
961 * Note the function throws exception should an error occur!
963 tcu::TestNode::IterateResult GeometryShaderGetProgramiv3Test::iterate()
965 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
966 glw::GLint gs_spo_id = 0;
967 unsigned int n_run = 0;
968 unsigned int n_separable_object_case = 0;
971 /* This test should only run if EXT_geometry_shader is supported. */
972 if (!m_is_geometry_shader_extension_supported)
974 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
977 /* Prepare specialized versions of dummy fragment & vertex shaders */
978 std::string dummy_fs_specialized = specializeShader(1,
979 /* parts */ &dummy_fs_code);
980 const char* dummy_fs_specialized_raw = dummy_fs_specialized.c_str();
981 std::string dummy_vs_specialized = specializeShader(1, &dummy_vs_code);
982 const char* dummy_vs_specialized_raw = dummy_vs_specialized.c_str();
984 /* Set up the fragment & the vertex shaders */
985 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
986 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
987 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
989 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
991 if (!buildShader(m_fs_id, dummy_fs_specialized_raw) || !buildShader(m_vs_id, dummy_vs_specialized_raw))
993 m_testCtx.getLog() << tcu::TestLog::Message << "Either FS or VS failed to build." << tcu::TestLog::EndMessage;
999 /* Set up the test program object */
1000 m_po_id = gl.createProgram();
1002 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1004 gl.attachShader(m_po_id, m_fs_id);
1005 gl.attachShader(m_po_id, m_gs_id);
1006 gl.attachShader(m_po_id, m_vs_id);
1007 GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call(s) failed.");
1009 /* Set up the fragment & the vertex shader programs */
1010 if (!buildShaderProgram(&m_fs_po_id, GL_FRAGMENT_SHADER, dummy_fs_specialized_raw) ||
1011 !buildShaderProgram(&m_vs_po_id, GL_VERTEX_SHADER, dummy_vs_specialized_raw))
1013 m_testCtx.getLog() << tcu::TestLog::Message << "Either FS or VS SPOs failed to build."
1014 << tcu::TestLog::EndMessage;
1020 /* Set up test runs */
1023 /* The test should check both a geometry shader program object and a full-blown PO
1024 * consisting of FS, GS and VS. */
1025 for (n_separable_object_case = 0; n_separable_object_case < 2; /* PO, SPO cases */
1026 ++n_separable_object_case)
1028 bool should_use_separable_object = (n_separable_object_case != 0);
1030 /* Iterate over all test runs */
1031 for (n_run = 0; n_run < _runs.size(); ++n_run)
1033 const _run& current_run = _runs[n_run];
1034 std::string gs_code = getGSCode(current_run);
1035 const char* gs_code_raw = gs_code.c_str();
1036 std::string gs_code_specialized = specializeShader(1, /* parts */
1038 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
1040 if (should_use_separable_object)
1042 /* Deinitialize any objects that may have been created in previous iterations */
1045 /* Set up the geometry shader program object */
1046 if (!buildShaderProgram(&m_gs_po_id, GL_GEOMETRY_SHADER, gs_code_specialized_raw))
1048 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to compile a geometry shader program object"
1049 << tcu::TestLog::EndMessage;
1054 } /* if (should_use_pipeline_object) */
1057 gl.bindProgramPipeline(0);
1058 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
1060 /* Set up the geometry shader object */
1061 if (!buildShader(m_gs_id, gs_code_specialized_raw))
1063 m_testCtx.getLog() << tcu::TestLog::Message << "Failed to compile a geometry shader object."
1064 << tcu::TestLog::EndMessage;
1070 /* Set up the program object */
1071 glw::GLint link_status = GL_FALSE;
1073 gl.linkProgram(m_po_id);
1074 GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
1076 gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
1078 if (link_status == GL_FALSE)
1080 m_testCtx.getLog() << tcu::TestLog::Message << "Test program object failed to link"
1081 << tcu::TestLog::EndMessage;
1087 /* Bind the PO to the rendering context */
1088 gl.useProgram(m_po_id);
1089 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
1092 /* Execute the queries */
1093 glw::GLuint po_id = (should_use_separable_object) ? m_gs_po_id : m_po_id;
1094 glw::GLint result_geometry_linked_vertices_out = 0;
1095 glw::GLint result_geometry_linked_input_type = 0;
1096 glw::GLint result_geometry_linked_output_type = 0;
1097 glw::GLint result_geometry_shader_invocations = 0;
1099 gl.getProgramiv(po_id, m_glExtTokens.GEOMETRY_LINKED_VERTICES_OUT, &result_geometry_linked_vertices_out);
1100 GLU_EXPECT_NO_ERROR(gl.getError(),
1101 "glGetProgramiv() call failed for GL_GEOMETRY_LINKED_VERTICES_OUT_EXT query.");
1103 gl.getProgramiv(po_id, m_glExtTokens.GEOMETRY_LINKED_INPUT_TYPE, &result_geometry_linked_input_type);
1104 GLU_EXPECT_NO_ERROR(gl.getError(),
1105 "glGetProgramiv() call failed for GL_GEOMETRY_LINKED_INPUT_TYPE_EXT query.");
1107 gl.getProgramiv(po_id, m_glExtTokens.GEOMETRY_LINKED_OUTPUT_TYPE, &result_geometry_linked_output_type);
1108 GLU_EXPECT_NO_ERROR(gl.getError(),
1109 "glGetProgramiv() call failed for GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT query.");
1111 gl.getProgramiv(po_id, m_glExtTokens.GEOMETRY_SHADER_INVOCATIONS, &result_geometry_shader_invocations);
1112 GLU_EXPECT_NO_ERROR(gl.getError(),
1113 "glGetProgramiv() call failed for GL_GEOMETRY_LINKED_INPUT_TYPE_EXT query.");
1115 if (current_run.input_primitive_type != (glw::GLenum)result_geometry_linked_input_type)
1117 m_testCtx.getLog() << tcu::TestLog::Message << "GL_GEOMETRY_LINKED_INPUT_TYPE_EXT query value "
1118 << "[" << result_geometry_linked_input_type
1120 " does not match the test run setting "
1122 << current_run.input_primitive_type << "]" << tcu::TestLog::EndMessage;
1127 if (current_run.invocations != result_geometry_shader_invocations)
1129 m_testCtx.getLog() << tcu::TestLog::Message << "GL_GEOMETRY_SHADER_INVOCATIONS_EXT query value "
1130 << "[" << result_geometry_shader_invocations
1132 " does not match the test run setting "
1134 << current_run.input_primitive_type << "]" << tcu::TestLog::EndMessage;
1139 if (current_run.max_vertices != result_geometry_linked_vertices_out)
1141 m_testCtx.getLog() << tcu::TestLog::Message << "GL_GEOMETRY_LINKED_VERTICES_OUT query value "
1142 << "[" << result_geometry_linked_vertices_out
1144 " does not match the test run setting "
1146 << current_run.max_vertices << "]" << tcu::TestLog::EndMessage;
1151 if (current_run.output_primitive_type != (glw::GLenum)result_geometry_linked_output_type)
1153 m_testCtx.getLog() << tcu::TestLog::Message << "GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT query value "
1154 << "[" << result_geometry_linked_output_type
1156 " does not match the test run setting "
1158 << current_run.output_primitive_type << "]" << tcu::TestLog::EndMessage;
1162 } /* for (all test runs) */
1163 } /* for (PO & SPO cases) */
1165 /* One more check: build a pipeline object which only defines a FS & VS stages,
1166 * and check what GS SPO ID the object reports. */
1167 gl.genProgramPipelines(1, &m_pipeline_object_id);
1168 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
1170 gl.useProgramStages(m_pipeline_object_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id);
1171 gl.useProgramStages(m_pipeline_object_id, GL_VERTEX_SHADER_BIT, m_vs_po_id);
1172 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
1174 gl.getProgramPipelineiv(m_pipeline_object_id, m_glExtTokens.GEOMETRY_SHADER, &gs_spo_id);
1175 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramPipelineiv() call failed.");
1179 m_testCtx.getLog() << tcu::TestLog::Message << "Pipeline object reported [" << gs_spo_id << "]"
1180 << " for GL_GEOMETRY_SHADER_EXT query, even though no GS SPO was bound."
1181 << tcu::TestLog::EndMessage;
1189 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1193 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1201 * @param context Test context
1202 * @param extParams Not used.
1203 * @param name Test case's name
1204 * @param description Test case's description
1206 GeometryShaderDrawCallWithFSAndGS::GeometryShaderDrawCallWithFSAndGS(Context& context, const ExtParameters& extParams,
1207 const char* name, const char* description)
1208 : TestCaseBase(context, extParams, name, description)
1211 , m_pipeline_object_id(0)
1216 /** Deinitializes GLES objects created during the test. */
1217 void GeometryShaderDrawCallWithFSAndGS::deinit()
1219 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1221 if (m_fs_po_id != 0)
1223 gl.deleteProgram(m_fs_po_id);
1228 if (m_gs_po_id != 0)
1230 gl.deleteProgram(m_gs_po_id);
1235 if (m_pipeline_object_id != 0)
1237 gl.deleteProgramPipelines(1, &m_pipeline_object_id);
1239 m_pipeline_object_id = 0;
1244 gl.deleteVertexArrays(1, &m_vao_id);
1249 /* Release base class */
1250 TestCaseBase::deinit();
1253 /** Executes the test.
1255 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1256 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1257 * Note the function throws exception should an error occur!
1259 tcu::TestNode::IterateResult GeometryShaderDrawCallWithFSAndGS::iterate()
1261 glw::GLenum error_code = GL_NO_ERROR;
1262 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1265 /* This test should only run if EXT_geometry_shader is supported. */
1266 if (!m_is_geometry_shader_extension_supported)
1268 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1271 /* Create & bind a VAO */
1272 gl.genVertexArrays(1, &m_vao_id);
1273 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
1275 gl.bindVertexArray(m_vao_id);
1276 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
1278 /* Create shader program objects */
1279 std::string code_fs_specialized = specializeShader(1, /* parts */
1281 const char* code_fs_specialized_raw = code_fs_specialized.c_str();
1282 std::string code_gs_specialized = specializeShader(1, /* parts */
1284 const char* code_gs_specialized_raw = code_gs_specialized.c_str();
1285 glw::GLint link_status = GL_FALSE;
1287 m_fs_po_id = gl.createShaderProgramv(GL_FRAGMENT_SHADER, 1, /* count */
1288 &code_fs_specialized_raw);
1289 m_gs_po_id = gl.createShaderProgramv(GL_GEOMETRY_SHADER, 1, /* count */
1290 &code_gs_specialized_raw);
1292 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShaderProgramv() call(s) failed.");
1294 gl.getProgramiv(m_fs_po_id, GL_LINK_STATUS, &link_status);
1296 if (link_status != GL_TRUE)
1298 m_testCtx.getLog() << tcu::TestLog::Message << "Dummy fragment shader program failed to link."
1299 << tcu::TestLog::EndMessage;
1305 gl.getProgramiv(m_gs_po_id, GL_LINK_STATUS, &link_status);
1307 if (link_status != GL_TRUE)
1309 m_testCtx.getLog() << tcu::TestLog::Message << "Dummy geometry shader program failed to link."
1310 << tcu::TestLog::EndMessage;
1316 /* Create & set up a pipeline object */
1317 gl.genProgramPipelines(1, &m_pipeline_object_id);
1318 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
1320 gl.useProgramStages(m_pipeline_object_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id);
1321 gl.useProgramStages(m_pipeline_object_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id);
1322 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed.");
1324 gl.bindProgramPipeline(m_pipeline_object_id);
1325 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
1327 /* Try to do a draw call */
1328 gl.drawArrays(GL_POINTS, 0, /* first */
1331 error_code = gl.getError();
1332 if (error_code != GL_INVALID_OPERATION)
1334 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid draw call generated an error code [" << error_code
1336 " which is different from the expected GL_INVALID_OPERATION."
1337 << tcu::TestLog::EndMessage;
1343 // m_pipeline_object_id is generated in this function, need to be freed
1344 if (m_pipeline_object_id)
1346 gl.deleteProgramPipelines(1, &m_pipeline_object_id);
1347 m_pipeline_object_id = 0;
1350 // m_gs_po_id is generated in this function, need to be freed
1353 gl.deleteProgram(m_gs_po_id);
1357 // m_fs_po_id is generated in this function, need to be freed
1360 gl.deleteProgram(m_fs_po_id);
1364 // m_vao_id is generated in this function, need to be freed
1367 gl.deleteVertexArrays(1, &m_vao_id);
1374 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1378 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1386 * @param context Test context
1387 * @param extParams Not used.
1388 * @param name Test case's name
1389 * @param description Test case's description
1391 GeometryShaderMaxImageUniformsTest::GeometryShaderMaxImageUniformsTest(Context& context, const ExtParameters& extParams,
1392 const char* name, const char* description)
1393 : TestCaseBase(context, extParams, name, description)
1395 , m_gl_max_geometry_image_uniforms_ext_value(0)
1398 , m_texture_ids(NULL)
1403 //Bug-15063 Only GLSL 4.50 supports opaque types
1404 if (m_glslVersion >= glu::GLSL_VERSION_130)
1406 m_glslVersion = glu::GLSL_VERSION_450;
1410 /** Deinitializes GLES objects created during the test. */
1411 void GeometryShaderMaxImageUniformsTest::deinit()
1413 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1417 gl.deleteShader(m_fs_id);
1424 gl.deleteShader(m_gs_id);
1431 gl.deleteProgram(m_po_id);
1436 if (m_texture_ids != NULL)
1438 gl.deleteTextures(m_gl_max_geometry_image_uniforms_ext_value, m_texture_ids);
1440 delete[] m_texture_ids;
1441 m_texture_ids = NULL;
1446 gl.deleteBuffers(1, &m_tfbo_id);
1452 gl.deleteVertexArrays(1, &m_vao_id);
1458 gl.deleteShader(m_vs_id);
1463 /* Set GL_PACK_ALIGNMENT to default value. */
1464 gl.pixelStorei(GL_PACK_ALIGNMENT, 4 /*default value taken from specification*/);
1465 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed for GL_PACK_ALIGNMENT pname.");
1467 /* Release base class */
1468 TestCaseBase::deinit();
1471 /* Retrieves test-specific geometry shader source code.
1473 * @return Requested string.
1475 std::string GeometryShaderMaxImageUniformsTest::getGSCode()
1477 std::stringstream code_sstream;
1480 code_sstream << "${VERSION}\n"
1481 "${GEOMETRY_SHADER_REQUIRE}\n"
1483 "layout (points) in;\n"
1484 "layout (points, max_vertices = 1) out;\n"
1486 "precision highp iimage2D;\n"
1488 "ivec4 counter = ivec4(0);\n"
1491 for (glw::GLint n_img = 0; n_img < (m_gl_max_geometry_image_uniforms_ext_value); ++n_img)
1493 code_sstream << "layout(binding = " << n_img << ", r32i) uniform iimage2D img" << n_img << ";\n";
1496 code_sstream << "\n"
1500 for (glw::GLint n_img = 0; n_img < (m_gl_max_geometry_image_uniforms_ext_value); ++n_img)
1502 code_sstream << " counter += imageLoad(img" << n_img << ", ivec2(0, 0));\n";
1505 code_sstream << "\n"
1506 " gl_Position = vec4(float(counter.x), 0.0, 0.0, 1.0);\n"
1510 /* Form a specialized version of the GS source code */
1511 std::string gs_code = code_sstream.str();
1512 const char* gs_code_raw = gs_code.c_str();
1513 std::string gs_code_specialized = specializeShader(1 /* parts */, &gs_code_raw);
1515 return gs_code_specialized;
1518 /** Executes the test.
1520 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1521 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1522 * Note the function throws exception should an error occur!
1524 tcu::TestNode::IterateResult GeometryShaderMaxImageUniformsTest::iterate()
1526 glw::GLint counter = 0;
1527 glw::GLint expectedValue = 0;
1528 bool has_shader_compilation_failed = true;
1529 glw::GLfloat* ptr = DE_NULL;
1531 const glw::GLchar* feedbackVaryings[] = { "gl_Position" };
1533 std::string fs_code_specialized = "";
1534 const char* fs_code_specialized_raw = DE_NULL;
1535 std::string gs_code_specialized = "";
1536 const char* gs_code_specialized_raw = DE_NULL;
1537 std::string vs_code_specialized = "";
1538 const char* vs_code_specialized_raw = DE_NULL;
1540 /* This test should only run if EXT_geometry_shader is supported. */
1541 if (!m_is_geometry_shader_extension_supported)
1543 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1546 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1548 /* Retrieve GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT pname value */
1549 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_IMAGE_UNIFORMS, &m_gl_max_geometry_image_uniforms_ext_value);
1550 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT pname");
1552 /* Retrieve GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT pname value */
1553 glw::GLint m_gl_max_geometry_texture_image_units_ext_value = 0;
1554 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &m_gl_max_geometry_texture_image_units_ext_value);
1555 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT pname");
1557 /* Check if m_gl_max_geometry_image_uniforms_value is less than or equal zero. */
1558 if (m_gl_max_geometry_image_uniforms_ext_value <= 0)
1560 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT query value "
1561 << "[" << m_gl_max_geometry_image_uniforms_ext_value
1563 " is less than or equal zero. Image uniforms in Geometry Shader"
1564 " are not supported."
1565 << tcu::TestLog::EndMessage;
1567 if (m_gl_max_geometry_image_uniforms_ext_value == 0)
1569 throw tcu::NotSupportedError("GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT is 0");
1578 /* Check if m_gl_max_geometry_texture_image_units_value is less than m_gl_max_geometry_image_uniforms_value. */
1579 if (m_gl_max_geometry_texture_image_units_ext_value < m_gl_max_geometry_image_uniforms_ext_value)
1581 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT query value "
1582 << "[" << m_gl_max_geometry_image_uniforms_ext_value
1584 " is greater than GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT query value "
1586 << m_gl_max_geometry_texture_image_units_ext_value << "]." << tcu::TestLog::EndMessage;
1592 /* Create a program object. */
1593 m_po_id = gl.createProgram();
1594 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1596 /* Create shader objects. */
1597 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1598 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1599 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1601 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1603 /* Configure which outputs should be captured by Transform Feedback. */
1604 gl.transformFeedbackVaryings(m_po_id, 1 /* varyings count */, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
1606 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
1608 /* Try to link the test program object */
1609 fs_code_specialized = specializeShader(1, &dummy_fs_code);
1610 fs_code_specialized_raw = fs_code_specialized.c_str();
1612 gs_code_specialized = getGSCode();
1613 gs_code_specialized_raw = gs_code_specialized.c_str();
1615 vs_code_specialized = specializeShader(1, &dummy_vs_code);
1616 vs_code_specialized_raw = vs_code_specialized.c_str();
1618 if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */
1619 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1620 &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1621 &fs_code_specialized_raw, &has_shader_compilation_failed))
1623 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
1630 gl.useProgram(m_po_id);
1631 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
1633 /* Allocate memory for m_max_image_units_value Texture Objects. */
1634 m_texture_ids = new glw::GLuint[m_gl_max_geometry_image_uniforms_ext_value];
1636 /* Generate m_max_image_units_value Texture Objects. */
1637 gl.genTextures(m_gl_max_geometry_image_uniforms_ext_value, m_texture_ids);
1638 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
1640 /* Set GL_PACK_ALIGNMENT to 1. */
1641 gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
1642 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed for GL_PACK_ALIGNMENT pname.");
1644 /* Bind integer 2D texture objects of resolution 1x1 to image units. */
1645 for (glw::GLint n_img = 0; n_img < (m_gl_max_geometry_image_uniforms_ext_value); ++n_img)
1647 glw::GLint texture = m_texture_ids[n_img];
1648 glw::GLint value = n_img + 1;
1650 gl.bindTexture(GL_TEXTURE_2D, texture);
1651 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
1653 gl.texStorage2D(GL_TEXTURE_2D, 1 /*levels*/, GL_R32I, 1 /*width*/, 1 /*height*/);
1654 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
1656 gl.texSubImage2D(GL_TEXTURE_2D, 0 /*level*/, 0 /*xoffset*/, 0 /*yoffset*/, 1 /*width*/, 1 /*height*/,
1657 GL_RED_INTEGER, GL_INT, &value);
1658 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
1660 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1661 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri() call failed.");
1663 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1664 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri() call failed.");
1666 gl.bindImageTexture(n_img, texture, 0 /*level*/, GL_FALSE /*is layered?*/, 0 /*layer*/, GL_READ_ONLY, GL_R32I);
1667 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed.");
1670 /* Configure VAO. */
1671 gl.genVertexArrays(1, &m_vao_id);
1672 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
1674 gl.bindVertexArray(m_vao_id);
1675 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
1677 /* Create a Buffer Object for Transform Feedback's outputs. */
1678 gl.genBuffers(1, &m_tfbo_id);
1679 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
1681 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
1682 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
1684 gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4 /* four float vector components */, NULL, GL_STATIC_READ);
1685 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
1687 /* Bind Buffer Object m_tfbo_id to GL_TRANSFORM_FEEDBACK_BUFFER binding point. */
1688 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_tfbo_id);
1689 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
1691 /* Disable rasterization and make a draw call. After that, turn on rasterization. */
1692 gl.enable(GL_RASTERIZER_DISCARD);
1693 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed for GL_RASTERIZER_DISCARD pname.");
1695 gl.beginTransformFeedback(GL_POINTS);
1696 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
1698 gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/);
1699 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
1701 gl.endTransformFeedback();
1702 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
1704 gl.disable(GL_RASTERIZER_DISCARD);
1705 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed for GL_RASTERIZER_DISCARD pname.");
1707 /* Retrieve value from Transform Feedback. */
1709 ptr = (glw::GLfloat*)gl.mapBufferRange(
1710 GL_ARRAY_BUFFER, 0, sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT);
1712 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
1714 counter = int(ptr[0] + 0.5f);
1716 gl.unmapBuffer(GL_ARRAY_BUFFER);
1717 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
1719 /* Calculate expected value. */
1720 expectedValue = m_gl_max_geometry_image_uniforms_ext_value * (m_gl_max_geometry_image_uniforms_ext_value + 1) / 2;
1722 if (counter != expectedValue)
1730 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1734 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1742 * @param context Test context
1743 * @param extParams Not used.
1744 * @param name Test case's name
1745 * @param description Test case's description
1747 GeometryShaderMaxShaderStorageBlocksTest::GeometryShaderMaxShaderStorageBlocksTest(Context& context,
1748 const ExtParameters& extParams,
1750 const char* description)
1751 : TestCaseBase(context, extParams, name, description)
1753 , m_gl_max_geometry_shader_storage_blocks_ext_value(0)
1763 /** Deinitializes GLES objects created during the test. */
1764 void GeometryShaderMaxShaderStorageBlocksTest::deinit()
1766 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1770 gl.deleteShader(m_fs_id);
1776 gl.deleteShader(m_gs_id);
1782 gl.deleteProgram(m_po_id);
1788 gl.deleteBuffers(1, &m_ssbo_id);
1794 gl.deleteBuffers(1, &m_tfbo_id);
1800 gl.deleteVertexArrays(1, &m_vao_id);
1806 gl.deleteShader(m_vs_id);
1810 /* Release base class */
1811 TestCaseBase::deinit();
1814 /* Retrieves test-specific geometry shader source code.
1816 * @return Requested string.
1818 std::string GeometryShaderMaxShaderStorageBlocksTest::getGSCode()
1820 std::stringstream code_sstream;
1823 code_sstream << "${VERSION}\n"
1824 "${GEOMETRY_SHADER_REQUIRE}\n"
1826 "layout (points) in;\n"
1827 "layout (points, max_vertices = 1) out;\n"
1829 "int counter = 0;\n"
1832 for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb)
1834 code_sstream << "layout(binding = " << n_ssb << ") buffer ssb" << n_ssb << " \n{\n"
1836 << "} S_SSB" << n_ssb << ";\n\n";
1839 code_sstream << "\n"
1843 for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb)
1845 code_sstream << " counter += S_SSB" << n_ssb << ".value++;\n";
1848 code_sstream << "\n"
1849 " gl_Position = vec4(float(counter), 0.0, 0.0, 1.0);\n"
1853 /* Form a specialized version of the GS source code */
1854 std::string gs_code = code_sstream.str();
1855 const char* gs_code_raw = gs_code.c_str();
1856 std::string gs_code_specialized = specializeShader(1 /* parts */, &gs_code_raw);
1858 return gs_code_specialized;
1861 /** Executes the test.
1863 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1864 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1865 * Note the function throws exception should an error occur!
1867 tcu::TestNode::IterateResult GeometryShaderMaxShaderStorageBlocksTest::iterate()
1869 glw::GLint counter = 0;
1870 glw::GLint expectedValue = 0;
1871 const glw::GLchar* feedbackVaryings[] = { "gl_Position" };
1872 bool has_shader_compilation_failed = true;
1873 const glw::GLfloat initial_buffer_data[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
1874 glw::GLint int_alignment = 0;
1875 const glw::GLint int_size = sizeof(glw::GLint);
1876 glw::GLint* ptrSSBO_data = DE_NULL;
1877 glw::GLfloat* ptrTF_data = DE_NULL;
1879 glw::GLint ssbo_alignment = 0;
1880 glw::GLint* ssbo_data = DE_NULL;
1881 glw::GLint ssbo_data_size = 0;
1883 std::string fs_code_specialized = "";
1884 const char* fs_code_specialized_raw = DE_NULL;
1885 std::string gs_code_specialized = "";
1886 const char* gs_code_specialized_raw = DE_NULL;
1887 std::string vs_code_specialized = "";
1888 const char* vs_code_specialized_raw = DE_NULL;
1890 /* This test should only run if EXT_geometry_shader is supported. */
1891 if (!m_is_geometry_shader_extension_supported)
1893 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1896 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1898 /* Retrieve GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT pname value */
1899 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_STORAGE_BLOCKS,
1900 &m_gl_max_geometry_shader_storage_blocks_ext_value);
1901 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT pname");
1903 /* Retrieve GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS pname value */
1904 glw::GLint m_gl_max_shader_storage_buffer_bindings_value = 0;
1906 gl.getIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &m_gl_max_shader_storage_buffer_bindings_value);
1907 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS pname");
1909 /* Check if m_gl_max_shader_storage_blocks_value is less than or equal zero. */
1910 if (m_gl_max_geometry_shader_storage_blocks_ext_value <= 0)
1912 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT query value "
1913 << "[" << m_gl_max_geometry_shader_storage_blocks_ext_value
1915 " is less than or equal zero. Shader Storage Blocks"
1916 " in Geometry Shader are not supported."
1917 << tcu::TestLog::EndMessage;
1919 if (m_gl_max_geometry_shader_storage_blocks_ext_value == 0)
1921 throw tcu::NotSupportedError("GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT is 0");
1930 /* Check if m_gl_max_shader_storage_buffer_bindings_value is less than m_gl_max_shader_storage_blocks_value. */
1931 if (m_gl_max_shader_storage_buffer_bindings_value < m_gl_max_geometry_shader_storage_blocks_ext_value)
1933 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT query value "
1934 << "[" << m_gl_max_geometry_shader_storage_blocks_ext_value
1936 " is greater than GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS query value "
1938 << m_gl_max_shader_storage_buffer_bindings_value << "]." << tcu::TestLog::EndMessage;
1944 /* Create a program object. */
1945 m_po_id = gl.createProgram();
1946 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1948 /* Create shader objects. */
1949 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1950 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1951 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1953 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1955 /* Configure which outputs should be captured by Transform Feedback. */
1956 gl.transformFeedbackVaryings(m_po_id, 1 /* varyings count */, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
1958 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
1960 /* Try to link the test program object */
1961 fs_code_specialized = specializeShader(1, &dummy_fs_code);
1962 fs_code_specialized_raw = fs_code_specialized.c_str();
1964 gs_code_specialized = getGSCode();
1965 gs_code_specialized_raw = gs_code_specialized.c_str();
1967 vs_code_specialized = specializeShader(1, &dummy_vs_code);
1968 vs_code_specialized_raw = vs_code_specialized.c_str();
1970 if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */
1971 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1972 &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1973 &fs_code_specialized_raw, &has_shader_compilation_failed))
1975 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
1981 /* Prepare data for Shader Storage Buffer Object. */
1982 gl.getIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_alignment);
1983 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed.");
1985 int_alignment = ssbo_alignment / int_size;
1986 ssbo_data_size = m_gl_max_geometry_shader_storage_blocks_ext_value * ssbo_alignment;
1987 ssbo_data = new glw::GLint[ssbo_data_size];
1989 if ((ssbo_alignment % int_size) != 0)
1991 m_testCtx.getLog() << tcu::TestLog::Message << "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT query value "
1993 << ssbo_alignment << "]"
1994 "divide with remainder by the size of GLint "
1996 << int_size << "]" << tcu::TestLog::EndMessage;
2002 for (int i = 0; i < m_gl_max_geometry_shader_storage_blocks_ext_value; ++i)
2004 ssbo_data[i * int_alignment] = i + 1;
2007 /* Create Shader Storage Buffer Object. */
2008 gl.genBuffers(1, &m_ssbo_id);
2009 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2011 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo_id);
2012 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname.");
2014 gl.bufferData(GL_SHADER_STORAGE_BUFFER, ssbo_data_size, ssbo_data, GL_DYNAMIC_COPY);
2015 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2017 /* Free unused memory. */
2021 /* Bind specific m_ssbo_id buffer region to a specific Shader Storage Buffer binding point. */
2022 for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb)
2024 glw::GLuint offset = n_ssb * ssbo_alignment;
2026 gl.bindBufferRange(GL_SHADER_STORAGE_BUFFER, n_ssb /*binding index*/, m_ssbo_id, offset, int_size);
2027 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed.");
2030 /* Configure VAO. */
2031 gl.genVertexArrays(1, &m_vao_id);
2032 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2034 gl.bindVertexArray(m_vao_id);
2035 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2037 /* Create a Buffer Object for Transform Feedback's outputs. */
2038 gl.genBuffers(1, &m_tfbo_id);
2039 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2041 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
2042 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
2044 gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4 /* four float vector components */, initial_buffer_data,
2046 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2048 /* Bind Buffer Object m_tfbo_id to GL_TRANSFORM_FEEDBACK_BUFFER binding point. */
2049 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id);
2050 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
2053 gl.useProgram(m_po_id);
2054 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2056 /* Disable rasterization and make a draw call. After that, turn on rasterization. */
2057 gl.enable(GL_RASTERIZER_DISCARD);
2058 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed for GL_RASTERIZER_DISCARD pname.");
2060 gl.beginTransformFeedback(GL_POINTS);
2061 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
2063 gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/);
2064 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
2066 gl.endTransformFeedback();
2067 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
2069 gl.disable(GL_RASTERIZER_DISCARD);
2070 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed for GL_RASTERIZER_DISCARD pname.");
2072 /* Retrieve value from Transform Feedback. */
2073 ptrTF_data = (glw::GLfloat*)gl.mapBufferRange(
2074 GL_ARRAY_BUFFER, 0 /*offset*/, sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT);
2075 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
2077 counter = int(ptrTF_data[0] + 0.5f);
2079 gl.unmapBuffer(GL_ARRAY_BUFFER);
2080 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
2084 /* Retrieve values from Shader Storage Buffer Object. */
2086 (glw::GLint*)gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0 /*offset*/, ssbo_data_size, GL_MAP_READ_BIT);
2087 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
2089 for (int i = 0; i < m_gl_max_geometry_shader_storage_blocks_ext_value; ++i)
2091 if (ptrSSBO_data[i * int_alignment] != i + 2)
2095 m_testCtx.getLog() << tcu::TestLog::Message << "Value read from Shader Storage Buffer "
2097 << ptrSSBO_data[i * int_alignment] << "] "
2100 << i * int_alignment << "]"
2101 "is not equal to expected value "
2103 << i + 2 << "]" << tcu::TestLog::EndMessage;
2109 gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
2110 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
2112 ptrSSBO_data = NULL;
2114 /* Calculate expected value. */
2116 m_gl_max_geometry_shader_storage_blocks_ext_value * (m_gl_max_geometry_shader_storage_blocks_ext_value + 1) / 2;
2118 if (counter != expectedValue)
2126 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2130 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2138 * @param context Test context
2139 * @param extParams Not used.
2140 * @param name Test case's name
2141 * @param description Test case's description
2143 GeometryShaderMaxAtomicCountersTest::GeometryShaderMaxAtomicCountersTest(Context& context,
2144 const ExtParameters& extParams,
2145 const char* name, const char* description)
2146 : TestCaseBase(context, extParams, name, description)
2149 , m_gl_max_geometry_atomic_counters_ext_value(0)
2157 /** Deinitializes GLES objects created during the test. */
2158 void GeometryShaderMaxAtomicCountersTest::deinit()
2160 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2164 gl.deleteBuffers(1, &m_acbo_id);
2170 gl.deleteShader(m_fs_id);
2176 gl.deleteShader(m_gs_id);
2182 gl.deleteProgram(m_po_id);
2188 gl.deleteVertexArrays(1, &m_vao_id);
2194 gl.deleteShader(m_vs_id);
2198 /* Release base class */
2199 TestCaseBase::deinit();
2202 /* Retrieves test-specific geometry shader source code.
2204 * @return Requested string.
2206 std::string GeometryShaderMaxAtomicCountersTest::getGSCode()
2208 std::stringstream code_sstream;
2211 code_sstream << "${VERSION}\n"
2212 "${GEOMETRY_SHADER_REQUIRE}\n"
2214 "layout (points) in;\n"
2215 "layout (points, max_vertices = 1) out;\n"
2217 "uniform int n_loop_iterations;\n"
2218 "flat in int vertex_id[];\n"
2221 code_sstream << "layout(binding = 0) uniform atomic_uint acs[" << m_gl_max_geometry_atomic_counters_ext_value
2226 " for (int counter_id = 1;\n"
2227 " counter_id <= n_loop_iterations;\n"
2230 " if ((vertex_id[0] % counter_id) == 0)\n"
2232 " atomicCounterIncrement(acs[counter_id - 1]);\n"
2236 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2240 /* Form a specialized version of the GS source code */
2241 std::string gs_code = code_sstream.str();
2242 const char* gs_code_raw = gs_code.c_str();
2243 std::string gs_code_specialized = specializeShader(1, /* parts */ &gs_code_raw);
2245 return gs_code_specialized;
2248 /** Executes the test.
2250 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2251 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2252 * Note the function throws exception should an error occur!
2254 tcu::TestNode::IterateResult GeometryShaderMaxAtomicCountersTest::iterate()
2256 /* Define Vertex Shader's code for the purpose of this test. */
2257 const char* vs_code = "${VERSION}\n"
2259 "flat out int vertex_id;\n"
2263 " vertex_id = gl_VertexID;\n"
2264 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2267 bool has_shader_compilation_failed = true;
2268 glw::GLuint* initial_ac_data = DE_NULL;
2269 const unsigned int n_draw_call_vertices = 4;
2270 glw::GLint n_loop_iterations_uniform_location = -1;
2271 glw::GLuint* ptrACBO_data = DE_NULL;
2274 std::string fs_code_specialized = "";
2275 const char* fs_code_specialized_raw = DE_NULL;
2276 std::string gs_code_specialized = "";
2277 const char* gs_code_specialized_raw = DE_NULL;
2278 std::string vs_code_specialized = "";
2279 const char* vs_code_specialized_raw = DE_NULL;
2281 /* This test should only run if EXT_geometry_shader is supported. */
2282 if (!m_is_geometry_shader_extension_supported)
2284 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2287 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2289 /* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname value */
2290 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &m_gl_max_geometry_atomic_counters_ext_value);
2291 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname");
2293 /* Check if m_gl_max_atomic_counters_value is less than or equal zero. */
2294 if (m_gl_max_geometry_atomic_counters_ext_value <= 0)
2296 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT query value "
2297 << "[" << m_gl_max_geometry_atomic_counters_ext_value
2299 " is less than or equal to zero. Atomic Counters"
2300 " in Geometry Shader are not supported."
2301 << tcu::TestLog::EndMessage;
2303 if (m_gl_max_geometry_atomic_counters_ext_value == 0)
2305 throw tcu::NotSupportedError("GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT is 0");
2314 /* Create a program object. */
2315 m_po_id = gl.createProgram();
2316 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2318 /* Create shader objects. */
2319 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2320 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2321 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2323 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2325 /* Try to link the test program object */
2326 fs_code_specialized = specializeShader(1, &dummy_fs_code);
2327 fs_code_specialized_raw = fs_code_specialized.c_str();
2329 gs_code_specialized = getGSCode();
2330 gs_code_specialized_raw = gs_code_specialized.c_str();
2332 vs_code_specialized = specializeShader(1, &vs_code);
2333 vs_code_specialized_raw = vs_code_specialized.c_str();
2335 if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */
2336 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
2337 &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
2338 &fs_code_specialized_raw, &has_shader_compilation_failed))
2340 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
2346 /* Create Atomic Counter Buffer Objects. */
2347 gl.genBuffers(1, &m_acbo_id);
2348 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2350 /* Prepare initial data - zeroes - to fill the Atomic Counter Buffer Object. */
2351 initial_ac_data = new glw::GLuint[m_gl_max_geometry_atomic_counters_ext_value];
2352 memset(initial_ac_data, 0, sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value);
2354 gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_id);
2355 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname.");
2357 gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value, NULL,
2359 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2361 gl.bufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/,
2362 sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value,
2363 initial_ac_data /*initialize with zeroes*/);
2364 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
2366 gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0 /*binding index*/, m_acbo_id /*buffer*/);
2367 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed.");
2369 /* Configure VAO. */
2370 gl.genVertexArrays(1, &m_vao_id);
2371 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2373 gl.bindVertexArray(m_vao_id);
2374 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2377 n_loop_iterations_uniform_location = gl.getUniformLocation(m_po_id, "n_loop_iterations");
2379 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed.");
2380 if (n_loop_iterations_uniform_location == -1)
2382 TCU_FAIL("n_loop_iterations uniform is considered inactive");
2386 gl.useProgram(m_po_id);
2387 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2389 gl.uniform1i(n_loop_iterations_uniform_location, m_gl_max_geometry_atomic_counters_ext_value);
2390 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
2393 /* Issue the draw call */
2394 gl.drawArrays(GL_POINTS, 0, n_draw_call_vertices);
2395 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
2397 /* Retrieve values from Atomic Counter Buffer Objects and check if these values are valid. */
2398 ptrACBO_data = (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/,
2399 sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value,
2401 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
2403 for (glw::GLint n_ac = 0; n_ac < m_gl_max_geometry_atomic_counters_ext_value; ++n_ac)
2405 unsigned int expected_value = 0;
2407 for (unsigned int n_draw_call_vertex = 0; n_draw_call_vertex < n_draw_call_vertices; ++n_draw_call_vertex)
2409 if ((n_draw_call_vertex % (n_ac + 1)) == 0)
2415 if (ptrACBO_data[n_ac] != expected_value)
2422 gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2423 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
2425 ptrACBO_data = NULL;
2430 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2434 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2442 * @param context Test context
2443 * @param extParams Not used.
2444 * @param name Test case's name
2445 * @param description Test case's description
2447 GeometryShaderMaxAtomicCounterBuffersTest::GeometryShaderMaxAtomicCounterBuffersTest(Context& context,
2448 const ExtParameters& extParams,
2450 const char* description)
2451 : TestCaseBase(context, extParams, name, description)
2454 , m_gl_max_atomic_counter_buffer_bindings_value(0)
2455 , m_gl_max_geometry_atomic_counter_buffers_ext_value(0)
2463 /** Deinitializes GLES objects created during the test. */
2464 void GeometryShaderMaxAtomicCounterBuffersTest::deinit()
2466 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2468 if (m_acbo_ids != NULL)
2470 if (m_gl_max_geometry_atomic_counter_buffers_ext_value > 0)
2472 gl.deleteBuffers(m_gl_max_geometry_atomic_counter_buffers_ext_value, m_acbo_ids);
2474 delete[] m_acbo_ids;
2481 gl.deleteShader(m_fs_id);
2487 gl.deleteShader(m_gs_id);
2493 gl.deleteProgram(m_po_id);
2499 gl.deleteVertexArrays(1, &m_vao_id);
2505 gl.deleteShader(m_vs_id);
2509 /* Release base class */
2510 TestCaseBase::deinit();
2513 /* Retrieves test-specific geometry shader source code.
2515 * @return Requested string.
2517 std::string GeometryShaderMaxAtomicCounterBuffersTest::getGSCode()
2519 std::stringstream code_sstream;
2522 code_sstream << "${VERSION}\n"
2523 "${GEOMETRY_SHADER_REQUIRE}\n"
2525 "layout (points) in;\n"
2526 "layout (points, max_vertices = 1) out;\n"
2528 "flat in int vertex_id[];\n"
2531 for (glw::GLint n_ac = 0; n_ac < (m_gl_max_geometry_atomic_counter_buffers_ext_value); ++n_ac)
2533 code_sstream << "layout(binding = " << n_ac << ") uniform atomic_uint ac" << n_ac << ";\n";
2536 code_sstream << "\n"
2539 " for(int counter_id = 1; counter_id <= "
2540 << m_gl_max_geometry_atomic_counter_buffers_ext_value
2541 << "; ++counter_id)\n"
2543 " if((vertex_id[0] % counter_id) == 0)\n"
2546 for (glw::GLint n_ac = 0; n_ac < (m_gl_max_geometry_atomic_counter_buffers_ext_value); ++n_ac)
2548 code_sstream << " atomicCounterIncrement(ac" << n_ac << ");\n";
2551 code_sstream << " }\n"
2554 code_sstream << "\n"
2555 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2559 /* Form a specialized version of the GS source code */
2560 std::string gs_code = code_sstream.str();
2561 const char* gs_code_raw = gs_code.c_str();
2562 std::string gs_code_specialized = specializeShader(1, /* parts */ &gs_code_raw);
2564 return gs_code_specialized;
2567 /** Executes the test.
2569 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2570 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2571 * Note the function throws exception should an error occur!
2573 tcu::TestNode::IterateResult GeometryShaderMaxAtomicCounterBuffersTest::iterate()
2575 /* Define Vertex Shader's code for the purpose of this test. */
2576 const char* vs_code = "${VERSION}\n"
2578 "flat out int vertex_id;\n"
2582 " vertex_id = gl_VertexID;\n"
2583 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2586 unsigned int expected_value = 0;
2587 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2588 bool has_shader_compilation_failed = true;
2589 const glw::GLuint initial_ac_data = 0;
2590 const glw::GLuint number_of_indices = 128 * m_gl_max_geometry_atomic_counter_buffers_ext_value;
2593 std::string fs_code_specialized = "";
2594 const char* fs_code_specialized_raw = DE_NULL;
2595 std::string gs_code_specialized = "";
2596 const char* gs_code_specialized_raw = DE_NULL;
2597 std::string vs_code_specialized = "";
2598 const char* vs_code_specialized_raw = DE_NULL;
2600 /* This test should only run if EXT_geometry_shader is supported. */
2601 if (!m_is_geometry_shader_extension_supported)
2603 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2606 /* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname value */
2607 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS,
2608 &m_gl_max_geometry_atomic_counter_buffers_ext_value);
2609 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname");
2611 /* Retrieve GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS pname value */
2612 gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &m_gl_max_atomic_counter_buffer_bindings_value);
2613 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS pname");
2615 /* Check if m_gl_max_geometry_atomic_counter_buffers_ext_value is less than or equal zero. */
2616 if (m_gl_max_geometry_atomic_counter_buffers_ext_value <= 0)
2618 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT query value "
2619 << "[" << m_gl_max_geometry_atomic_counter_buffers_ext_value
2621 " is less than or equal to zero. Atomic Counter Buffers"
2622 " are not supported."
2623 << tcu::TestLog::EndMessage;
2625 if (m_gl_max_geometry_atomic_counter_buffers_ext_value == 0)
2627 throw tcu::NotSupportedError("GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT is 0");
2636 /* Check if m_gl_max_atomic_counter_buffer_bindings_value is less than m_gl_max_shader_storage_blocks_value. */
2637 if (m_gl_max_atomic_counter_buffer_bindings_value < m_gl_max_geometry_atomic_counter_buffers_ext_value)
2639 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT query value "
2640 << "[" << m_gl_max_geometry_atomic_counter_buffers_ext_value
2642 " is greater than GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS query value "
2644 << m_gl_max_atomic_counter_buffer_bindings_value << "]." << tcu::TestLog::EndMessage;
2650 /* Create a program object. */
2651 m_po_id = gl.createProgram();
2652 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2654 /* Create shader objects. */
2655 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2656 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2657 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2659 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2661 /* Try to link the test program object */
2662 fs_code_specialized = specializeShader(1, &dummy_fs_code);
2663 fs_code_specialized_raw = fs_code_specialized.c_str();
2665 gs_code_specialized = getGSCode();
2666 gs_code_specialized_raw = gs_code_specialized.c_str();
2668 vs_code_specialized = specializeShader(1, &vs_code);
2669 vs_code_specialized_raw = vs_code_specialized.c_str();
2671 if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */
2672 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
2673 &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
2674 &fs_code_specialized_raw, &has_shader_compilation_failed))
2676 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
2682 /* Create Atomic Counter Buffer Objects. */
2683 m_acbo_ids = new glw::GLuint[m_gl_max_geometry_atomic_counter_buffers_ext_value];
2685 gl.genBuffers(m_gl_max_geometry_atomic_counter_buffers_ext_value, m_acbo_ids);
2686 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2688 for (glw::GLint n_acb = 0; n_acb < m_gl_max_geometry_atomic_counter_buffers_ext_value; ++n_acb)
2690 gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_ids[n_acb]);
2691 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname.");
2693 gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(glw::GLuint), &initial_ac_data /*initialize with zeroes*/,
2695 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2697 gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, n_acb /*binding index*/, m_acbo_ids[n_acb] /*buffer*/);
2698 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed.");
2701 /* Configure VAO. */
2702 gl.genVertexArrays(1, &m_vao_id);
2703 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2705 gl.bindVertexArray(m_vao_id);
2706 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2709 gl.useProgram(m_po_id);
2710 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2712 gl.drawArrays(GL_POINTS, 0 /*starting index*/, number_of_indices);
2713 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
2715 /* Calculate expected value. */
2716 /* For each point being processed by Geometry Shader. */
2717 for (glw::GLuint vertex_id = 0; vertex_id < number_of_indices; ++vertex_id)
2719 /* And for each atomic counter ID. */
2720 for (int atomic_counter_id = 1; atomic_counter_id <= m_gl_max_geometry_atomic_counter_buffers_ext_value;
2721 ++atomic_counter_id)
2723 /* Check if (vertex_id % atomic_counter_id) == 0. If it is true, increment expected_value. */
2724 if (vertex_id % atomic_counter_id == 0)
2731 /* Retrieve values from Atomic Counter Buffer Objects and check if these values are valid. */
2732 for (glw::GLint n_acb = 0; n_acb < m_gl_max_geometry_atomic_counter_buffers_ext_value; ++n_acb)
2734 gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_ids[n_acb]);
2735 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
2737 glw::GLuint* ptrABO_data = (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/,
2738 sizeof(glw::GLuint) /*length*/, GL_MAP_READ_BIT);
2739 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
2741 if (ptrABO_data[0] != expected_value)
2747 gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2748 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
2756 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2760 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2768 * @param context Test context
2769 * @param extParams Not used.
2770 * @param name Test case's name
2771 * @param description Test case's description
2773 GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest::
2774 GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest(Context& context, const ExtParameters& extParams,
2775 const char* name, const char* description)
2776 : TestCaseBase(context, extParams, name, description)
2786 /** Deinitializes GLES objects created during the test. */
2787 void GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest::deinit()
2789 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2793 gl.deleteShader(m_fs_id);
2797 if (m_fs_po_id != 0)
2799 gl.deleteProgram(m_fs_po_id);
2805 gl.deleteShader(m_gs_id);
2809 if (m_gs_po_id != 0)
2811 gl.deleteProgram(m_gs_po_id);
2817 gl.deleteProgramPipelines(1, &m_ppo_id);
2823 gl.deleteVertexArrays(1, &m_vao_id);
2827 /* Release base class */
2828 TestCaseBase::deinit();
2831 /** Executes the test.
2833 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2834 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2835 * Note the function throws exception should an error occur!
2837 tcu::TestNode::IterateResult GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest::iterate()
2839 bool has_shader_compilation_failed = true;
2841 glw::GLenum error = GL_NO_ERROR;
2843 /* This test should only run if EXT_geometry_shader is supported. */
2844 if (!m_is_geometry_shader_extension_supported)
2846 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2849 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2851 /* Create separable program objects. */
2852 m_fs_po_id = gl.createProgram();
2853 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2855 gl.programParameteri(m_fs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2856 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
2858 m_gs_po_id = gl.createProgram();
2859 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2861 gl.programParameteri(m_gs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2862 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
2864 /* Create shader objects. */
2865 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2866 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2868 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2870 /* Try to link the test program object */
2871 std::string fs_code_specialized = specializeShader(1, &dummy_fs_code);
2872 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
2873 std::string gs_code_specialized = specializeShader(1, &dummy_gs_code);
2874 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
2876 if (!TestCaseBase::buildProgram(m_fs_po_id, m_fs_id, 1, /* n_sh1_body_parts */
2877 &fs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */
2878 NULL, 0, 0, /* n_sh3_body_parts */
2879 NULL, &has_shader_compilation_failed))
2881 m_testCtx.getLog() << tcu::TestLog::Message << "Fragment Shader Program object linking failed."
2882 << tcu::TestLog::EndMessage;
2888 if (!TestCaseBase::buildProgram(m_gs_po_id, m_gs_id, 1, /* n_sh1_body_parts */
2889 &gs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */
2890 NULL, 0, 0, /* n_sh3_body_parts */
2891 NULL, &has_shader_compilation_failed))
2893 m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed."
2894 << tcu::TestLog::EndMessage;
2900 /* Configure Pipeline Object. */
2901 gl.genProgramPipelines(1, &m_ppo_id);
2902 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
2904 gl.useProgramStages(m_ppo_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id);
2905 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
2907 gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id);
2908 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
2910 /* Configure VAO. */
2911 gl.genVertexArrays(1, &m_vao_id);
2912 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2914 gl.bindVertexArray(m_vao_id);
2915 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2917 /* Use Program Pipeline Object. */
2918 gl.bindProgramPipeline(m_ppo_id);
2919 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
2921 gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/);
2923 error = gl.getError();
2925 /* Check if correct error was generated. */
2926 if (GL_INVALID_OPERATION != error)
2930 m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPEARATION was generated."
2931 << tcu::TestLog::EndMessage;
2937 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2941 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2949 * @param context Test context
2950 * @param extParams Not used.
2951 * @param name Test case's name
2952 * @param description Test case's description
2954 GeometryShaderIncompatibleDrawCallModeTest::GeometryShaderIncompatibleDrawCallModeTest(Context& context,
2955 const ExtParameters& extParams,
2957 const char* description)
2958 : TestCaseBase(context, extParams, name, description)
2961 , m_number_of_gs(5 /*taken from test spec*/)
2968 /** Deinitializes GLES objects created during the test. */
2969 void GeometryShaderIncompatibleDrawCallModeTest::deinit()
2971 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2975 gl.deleteShader(m_fs_id);
2981 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2983 gl.deleteShader(m_gs_ids[i]);
2993 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2995 gl.deleteProgram(m_po_ids[i]);
3005 gl.deleteVertexArrays(1, &m_vao_id);
3011 gl.deleteShader(m_vs_id);
3015 /* Release base class */
3016 TestCaseBase::deinit();
3019 /** Executes the test.
3021 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
3022 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
3023 * Note the function throws exception should an error occur!
3025 tcu::TestNode::IterateResult GeometryShaderIncompatibleDrawCallModeTest::iterate()
3027 /* Define 5 Geometry Shaders for purpose of this test. */
3028 const char* gs_code_points = "${VERSION}\n"
3029 "${GEOMETRY_SHADER_REQUIRE}\n"
3031 "layout (points) in;\n"
3032 "layout (points, max_vertices = 1) out;\n"
3034 "${IN_PER_VERTEX_DECL_ARRAY}"
3038 " gl_Position = gl_in[0].gl_Position;\n"
3042 const char* gs_code_lines = "${VERSION}\n"
3043 "${GEOMETRY_SHADER_REQUIRE}\n"
3045 "layout (lines) in;\n"
3046 "layout (points, max_vertices = 1) out;\n"
3048 "${IN_PER_VERTEX_DECL_ARRAY}"
3052 " gl_Position = gl_in[0].gl_Position;\n"
3056 const char* gs_code_lines_adjacency = "${VERSION}\n"
3057 "${GEOMETRY_SHADER_REQUIRE}\n"
3059 "layout (lines_adjacency) in;\n"
3060 "layout (points, max_vertices = 1) out;\n"
3062 "${IN_PER_VERTEX_DECL_ARRAY}"
3066 " gl_Position = gl_in[0].gl_Position;\n"
3070 const char* gs_code_triangles = "${VERSION}\n"
3071 "${GEOMETRY_SHADER_REQUIRE}\n"
3073 "layout (triangles) in;\n"
3074 "layout (points, max_vertices = 1) out;\n"
3076 "${IN_PER_VERTEX_DECL_ARRAY}"
3080 " gl_Position = gl_in[0].gl_Position;\n"
3084 const char* gs_code_triangles_adjacency = "${VERSION}\n"
3085 "${GEOMETRY_SHADER_REQUIRE}\n"
3087 "layout (triangles_adjacency) in;\n"
3088 "layout (points, max_vertices = 1) out;\n"
3090 "${IN_PER_VERTEX_DECL_ARRAY}"
3094 " gl_Position = gl_in[0].gl_Position;\n"
3098 bool has_shader_compilation_failed = true;
3101 m_gs_ids = new glw::GLuint[m_number_of_gs];
3102 m_po_ids = new glw::GLuint[m_number_of_gs];
3104 /* This test should only run if EXT_geometry_shader is supported. */
3105 if (!m_is_geometry_shader_extension_supported)
3107 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
3110 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3112 /* Create program objects & geometry shader objects. */
3113 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3115 m_gs_ids[i] = gl.createShader(GL_GEOMETRY_SHADER);
3116 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
3118 m_po_ids[i] = gl.createProgram();
3119 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3122 /* Create shader object. */
3123 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
3124 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
3125 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3127 /* Try to link the test program object */
3128 std::string fs_code_specialized = specializeShader(1, &dummy_fs_code);
3129 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
3131 std::string gs_codes_specialized[] = { specializeShader(1, &gs_code_points), specializeShader(1, &gs_code_lines),
3132 specializeShader(1, &gs_code_lines_adjacency),
3133 specializeShader(1, &gs_code_triangles),
3134 specializeShader(1, &gs_code_triangles_adjacency) };
3136 const char* gs_codes_specialized_raw[] = { gs_codes_specialized[0].c_str(), gs_codes_specialized[1].c_str(),
3137 gs_codes_specialized[2].c_str(), gs_codes_specialized[3].c_str(),
3138 gs_codes_specialized[4].c_str() };
3139 std::string vs_code_specialized = specializeShader(1, &dummy_vs_code);
3140 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
3142 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3144 if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */
3145 &fs_code_specialized_raw, m_gs_ids[i], 1, /* n_sh2_body_parts */
3146 &gs_codes_specialized_raw[i], m_vs_id, 1, /* n_sh3_body_parts */
3147 &vs_code_specialized_raw, &has_shader_compilation_failed))
3149 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed for i = "
3150 << "[" << i << "]." << tcu::TestLog::EndMessage;
3159 /* Configure VAO. */
3160 gl.genVertexArrays(1, &m_vao_id);
3161 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
3163 gl.bindVertexArray(m_vao_id);
3164 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
3166 for (glw::GLuint po = 0; po < m_number_of_gs; ++po)
3168 /* Use Program Object. */
3169 gl.useProgram(m_po_ids[po]);
3170 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
3174 gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/);
3176 if (GL_INVALID_OPERATION != gl.getError())
3180 m_testCtx.getLog() << tcu::TestLog::Message
3181 << "Error different than GL_INVALID_OPEARATION was generated."
3182 << tcu::TestLog::EndMessage;
3190 gl.drawArrays(GL_LINES, 0 /*starting index*/, 2 /*number of indices*/);
3192 if (GL_INVALID_OPERATION != gl.getError())
3196 m_testCtx.getLog() << tcu::TestLog::Message
3197 << "Error different than GL_INVALID_OPEARATION was generated."
3198 << tcu::TestLog::EndMessage;
3203 gl.drawArrays(GL_LINE_LOOP, 0 /*starting index*/, 2 /*number of indices*/);
3205 if (GL_INVALID_OPERATION != gl.getError())
3209 m_testCtx.getLog() << tcu::TestLog::Message
3210 << "Error different than GL_INVALID_OPEARATION was generated."
3211 << tcu::TestLog::EndMessage;
3216 gl.drawArrays(GL_LINE_STRIP, 0 /*starting index*/, 2 /*number of indices*/);
3218 if (GL_INVALID_OPERATION != gl.getError())
3222 m_testCtx.getLog() << tcu::TestLog::Message
3223 << "Error different than GL_INVALID_OPEARATION was generated."
3224 << tcu::TestLog::EndMessage;
3232 gl.drawArrays(GL_LINES_ADJACENCY_EXT, 0 /*starting index*/, 4 /*number of indices*/);
3234 if (GL_INVALID_OPERATION != gl.getError())
3238 m_testCtx.getLog() << tcu::TestLog::Message
3239 << "Error different than GL_INVALID_OPEARATION was generated."
3240 << tcu::TestLog::EndMessage;
3245 gl.drawArrays(GL_LINE_STRIP_ADJACENCY_EXT, 0 /*starting index*/, 4 /*number of indices*/);
3247 if (GL_INVALID_OPERATION != gl.getError())
3251 m_testCtx.getLog() << tcu::TestLog::Message
3252 << "Error different than GL_INVALID_OPEARATION was generated."
3253 << tcu::TestLog::EndMessage;
3261 gl.drawArrays(GL_TRIANGLES, 0 /*starting index*/, 3 /*number of indices*/);
3263 if (GL_INVALID_OPERATION != gl.getError())
3267 m_testCtx.getLog() << tcu::TestLog::Message
3268 << "Error different than GL_INVALID_OPEARATION was generated."
3269 << tcu::TestLog::EndMessage;
3274 gl.drawArrays(GL_TRIANGLE_FAN, 0 /*starting index*/, 3 /*number of indices*/);
3276 if (GL_INVALID_OPERATION != gl.getError())
3280 m_testCtx.getLog() << tcu::TestLog::Message
3281 << "Error different than GL_INVALID_OPEARATION was generated."
3282 << tcu::TestLog::EndMessage;
3287 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /*starting index*/, 3 /*number of indices*/);
3289 if (GL_INVALID_OPERATION != gl.getError())
3293 m_testCtx.getLog() << tcu::TestLog::Message
3294 << "Error different than GL_INVALID_OPEARATION was generated."
3295 << tcu::TestLog::EndMessage;
3303 gl.drawArrays(GL_TRIANGLES_ADJACENCY_EXT, 0 /*starting index*/, 6 /*number of indices*/);
3305 if (GL_INVALID_OPERATION != gl.getError())
3309 m_testCtx.getLog() << tcu::TestLog::Message
3310 << "Error different than GL_INVALID_OPEARATION was generated."
3311 << tcu::TestLog::EndMessage;
3316 gl.drawArrays(GL_TRIANGLE_STRIP_ADJACENCY_EXT, 0 /*starting index*/, 6 /*number of indices*/);
3318 if (GL_INVALID_OPERATION != gl.getError())
3322 m_testCtx.getLog() << tcu::TestLog::Message
3323 << "Error different than GL_INVALID_OPEARATION was generated."
3324 << tcu::TestLog::EndMessage;
3334 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3338 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3346 * @param context Test context
3347 * @param extParams Not used.
3348 * @param name Test case's name
3349 * @param description Test case's description
3351 GeometryShaderInsufficientEmittedVerticesTest::GeometryShaderInsufficientEmittedVerticesTest(
3352 Context& context, const ExtParameters& extParams, const char* name, const char* description)
3353 : TestCaseBase(context, extParams, name, description)
3357 , m_number_of_color_components(4)
3358 , m_number_of_gs(2 /*taken from test spec*/)
3360 , m_texture_height(16)
3362 , m_texture_width(16)
3367 /* Allocate enough memory for glReadPixels() data which is respectively: width, height, RGBA components number. */
3368 m_pixels = new glw::GLubyte[m_texture_height * m_texture_width * m_number_of_color_components];
3371 /** Deinitializes GLES objects created during the test. */
3372 void GeometryShaderInsufficientEmittedVerticesTest::deinit()
3374 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3376 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
3378 if (m_pixels != NULL)
3386 gl.deleteFramebuffers(1, &m_fbo_id);
3392 gl.deleteShader(m_fs_id);
3398 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3400 gl.deleteShader(m_gs_ids[i]);
3410 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3412 gl.deleteProgram(m_po_ids[i]);
3420 if (m_texture_id != 0)
3422 gl.deleteTextures(1, &m_texture_id);
3428 gl.deleteVertexArrays(1, &m_vao_id);
3434 gl.deleteShader(m_vs_id);
3438 /* Release base class */
3439 TestCaseBase::deinit();
3442 /** Executes the test.
3444 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
3445 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
3446 * Note the function throws exception should an error occur!
3448 tcu::TestNode::IterateResult GeometryShaderInsufficientEmittedVerticesTest::iterate()
3450 /* Define Fragment Shader for purpose of this test. */
3451 const char* fs_code = "${VERSION}\n"
3453 "precision highp float;\n"
3455 "out vec4 result;\n"
3459 " result = vec4(1.0, 0.0, 0.0, 0.0);\n"
3462 /* Define 2 Geometry Shaders for purpose of this test. */
3463 const char* gs_line_strip = "${VERSION}\n"
3464 "${GEOMETRY_SHADER_REQUIRE}\n"
3466 "layout (points) in;\n"
3467 "layout (line_strip, max_vertices = 2) out;\n"
3469 "${IN_PER_VERTEX_DECL_ARRAY}"
3473 " gl_Position = gl_in[0].gl_Position;\n"
3474 " gl_Position.zw = vec2(0.0, 1.0);\n"
3478 const char* gs_triangle_strip = "${VERSION}\n"
3479 "${GEOMETRY_SHADER_REQUIRE}\n"
3481 "layout (points) in;\n"
3482 "layout (triangle_strip, max_vertices = 3) out;\n"
3484 "${IN_PER_VERTEX_DECL_ARRAY}"
3488 " gl_Position = gl_in[0].gl_Position;\n"
3489 " gl_Position.zw = vec2(0.0, 1.0);\n"
3492 " gl_Position = gl_in[0].gl_Position;\n"
3493 " gl_Position.zw = vec2(0.0, 1.0);\n"
3497 bool has_shader_compilation_failed = true;
3500 m_gs_ids = new glw::GLuint[m_number_of_gs];
3501 m_po_ids = new glw::GLuint[m_number_of_gs];
3503 /* This test should only run if EXT_geometry_shader is supported. */
3504 if (!m_is_geometry_shader_extension_supported)
3506 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
3509 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3511 /* Create program objects & geometry shader objects. */
3512 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3514 m_gs_ids[i] = gl.createShader(GL_GEOMETRY_SHADER);
3515 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
3517 m_po_ids[i] = gl.createProgram();
3518 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3521 /* Create shader object. */
3522 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
3523 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
3524 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3526 /* Try to link the test program object */
3527 std::string fs_code_specialized = specializeShader(1, &fs_code);
3528 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
3530 std::string gs_codes_specialized[] = { specializeShader(1, &gs_line_strip),
3531 specializeShader(1, &gs_triangle_strip) };
3533 const char* gs_codes_specialized_raw[] = { gs_codes_specialized[0].c_str(), gs_codes_specialized[1].c_str() };
3535 std::string vs_code_specialized = specializeShader(1, &dummy_vs_code);
3536 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
3538 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3540 if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */
3541 &fs_code_specialized_raw, m_gs_ids[i], 1, /* n_sh2_body_parts */
3542 &gs_codes_specialized_raw[i], m_vs_id, 1, /* n_sh3_body_parts */
3543 &vs_code_specialized_raw, &has_shader_compilation_failed))
3545 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed for i = "
3546 << "[" << i << "]." << tcu::TestLog::EndMessage;
3555 /* Create a 2D texture. */
3556 gl.genTextures(1, &m_texture_id);
3557 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
3559 gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
3560 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
3562 gl.texStorage2D(GL_TEXTURE_2D, 1 /*levels*/, GL_RGBA8, 16 /*width taken from spec*/,
3563 16 /*height taken from spec*/);
3564 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
3566 /* Configure FBO. */
3567 gl.genFramebuffers(1, &m_fbo_id);
3568 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
3570 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
3571 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
3573 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0 /*level*/);
3574 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
3576 /* Configure VAO. */
3577 gl.genVertexArrays(1, &m_vao_id);
3578 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
3580 gl.bindVertexArray(m_vao_id);
3581 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
3583 gl.clearColor(0.0f, 1.0f, 0.0f, 0.0f);
3584 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");
3586 for (glw::GLuint po = 0; po < m_number_of_gs; ++po)
3588 /* Use Program Object. */
3589 gl.useProgram(m_po_ids[po]);
3590 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
3592 gl.clear(GL_COLOR_BUFFER_BIT);
3593 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
3595 gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/);
3596 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
3598 gl.readPixels(0 /*x*/, 0 /*y*/, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
3599 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
3601 for (glw::GLuint pixel = 0; pixel < (m_texture_width * m_texture_height * m_number_of_color_components -
3602 m_number_of_color_components);
3603 pixel += m_number_of_color_components)
3605 if (m_pixels[pixel] != 0 && m_pixels[pixel + 1] != 255 && m_pixels[pixel + 2] != 0 &&
3606 m_pixels[pixel + 3] != 0)
3610 m_testCtx.getLog() << tcu::TestLog::Message << "Pixel [" << pixel << "] has color = ["
3611 << m_pixels[pixel] << ", " << m_pixels[pixel + 1] << ", " << m_pixels[pixel + 2]
3612 << ", " << m_pixels[pixel + 3] << "] "
3613 << "instead of [0, 255, 0, 0]." << tcu::TestLog::EndMessage;
3623 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3627 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3635 * @param context Test context
3636 * @param extParams Not used.
3637 * @param name Test case's name
3638 * @param description Test case's description
3640 GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest::
3641 GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest(Context& context,
3642 const ExtParameters& extParams,
3644 const char* description)
3645 : TestCaseBase(context, extParams, name, description)
3656 /** Deinitializes GLES objects created during the test. */
3657 void GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest::deinit()
3659 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3663 gl.deleteShader(m_gs_id);
3667 if (m_gs_po_id != 0)
3669 gl.deleteProgram(m_gs_po_id);
3675 gl.deleteProgramPipelines(1, &m_ppo_id);
3681 gl.deleteBuffers(1, &m_tfbo_id);
3687 gl.deleteVertexArrays(1, &m_vao_id);
3693 gl.deleteShader(m_vs_id);
3697 if (m_vs_po_id != 0)
3699 gl.deleteProgram(m_vs_po_id);
3703 /* Release base class */
3704 TestCaseBase::deinit();
3707 /** Executes the test.
3709 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
3710 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
3711 * Note the function throws exception should an error occur!
3713 tcu::TestNode::IterateResult GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest::iterate()
3715 /* Define Geometry Shader for purpose of this test. */
3716 const char* gs_code =
3718 "${GEOMETRY_SHADER_REQUIRE}\n"
3719 "${IN_PER_VERTEX_DECL_ARRAY}\n"
3720 "${OUT_PER_VERTEX_DECL}\n"
3722 "layout (points) in;\n"
3723 "layout (points, max_vertices = 1) out;\n"
3725 "flat in int vertexID[];\n"
3726 "flat in ivec4 out_vs_1[];\n"
3728 "out vec4 out_gs_1;\n"
3732 " out_gs_1 = vec4(vertexID[0] * 2, vertexID[0] * 2 + 1, vertexID[0] * 2 + 2, vertexID[0] * 2 + 3);\n"
3733 " gl_Position = vec4(0, 0, 0, 1);\n"
3737 /* Define Vertex Shader for purpose of this test. */
3738 const char* vs_code = "${VERSION}\n"
3739 "${OUT_PER_VERTEX_DECL}\n"
3741 "flat out ivec4 out_vs_1;\n"
3742 "flat out int vertexID;\n"
3746 " vertexID = gl_VertexID;\n"
3747 " out_vs_1 = ivec4(gl_VertexID, gl_VertexID + 1, gl_VertexID + 2, gl_VertexID + 3);\n"
3748 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
3751 bool has_shader_compilation_failed = true;
3753 glw::GLfloat* ptrTF_data_f = NULL;
3754 glw::GLuint* ptrTF_data_ui = NULL;
3755 glw::GLfloat expected_geom_results[] = { 0.0f, 1.0f, 2.0f, 3.0f };
3756 glw::GLuint expected_vertex_results[] = { 0, 1, 2, 3 };
3757 glw::GLfloat epsilon = 1e-5f;
3759 /* This test should only run if EXT_geometry_shader is supported. */
3760 if (!m_is_geometry_shader_extension_supported)
3762 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
3765 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3767 /* Create separable program objects. */
3768 m_gs_po_id = gl.createProgram();
3769 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
3771 gl.programParameteri(m_gs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
3772 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
3774 m_vs_po_id = gl.createProgram();
3775 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
3777 gl.programParameteri(m_vs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
3778 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
3780 /* Create shader objects. */
3781 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
3782 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
3783 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3785 /* Try to link the test program object */
3786 std::string gs_code_specialized = specializeShader(1, &gs_code);
3787 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
3789 std::string vs_code_specialized = specializeShader(1, &vs_code);
3790 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
3792 /* Specify output variables to be captured. */
3793 const char* tf_varyings[2] = { "out_gs_1", "out_vs_1" };
3795 gl.transformFeedbackVaryings(m_gs_po_id, 1 /*count*/, &tf_varyings[0], GL_INTERLEAVED_ATTRIBS);
3796 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
3798 gl.transformFeedbackVaryings(m_vs_po_id, 1 /*count*/, &tf_varyings[1], GL_INTERLEAVED_ATTRIBS);
3799 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
3801 if (!TestCaseBase::buildProgram(m_gs_po_id, m_gs_id, 1, /* n_sh1_body_parts */
3802 &gs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */
3803 NULL, 0, 0, /* n_sh3_body_parts */
3804 NULL, &has_shader_compilation_failed))
3806 m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed."
3807 << tcu::TestLog::EndMessage;
3813 if (!TestCaseBase::buildProgram(m_vs_po_id, m_vs_id, 1, /* n_sh1_body_parts */
3814 &vs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */
3815 NULL, 0, 0, /* n_sh3_body_parts */
3816 NULL, &has_shader_compilation_failed))
3818 m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed."
3819 << tcu::TestLog::EndMessage;
3825 /* Create and configure Program Pipeline Object. */
3826 gl.genProgramPipelines(1, &m_ppo_id);
3827 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call(s) failed.");
3829 gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id);
3830 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed.");
3832 gl.useProgramStages(m_ppo_id, GL_VERTEX_SHADER_BIT, m_vs_po_id);
3833 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed.");
3835 /* Create Vertex Array Object. */
3836 gl.genVertexArrays(1, &m_vao_id);
3837 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed.");
3839 gl.bindVertexArray(m_vao_id);
3840 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed.");
3842 /* Create Buffer Object for Transform Feedback data. */
3843 gl.genBuffers(1, &m_tfbo_id);
3844 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");
3846 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
3847 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");
3849 gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4, NULL, GL_STREAM_READ);
3850 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed.");
3852 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id);
3853 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed.");
3855 /* Ensure that there is no program object already bound and bind program pipeline. */
3857 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed.");
3859 gl.bindProgramPipeline(m_ppo_id);
3860 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call(s) failed.");
3862 gl.enable(GL_RASTERIZER_DISCARD);
3863 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed.");
3865 /* First pass - Vertex and Geometry Shaders On. */
3866 gl.beginTransformFeedback(GL_POINTS);
3867 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed.");
3869 gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/);
3870 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call(s) failed.");
3872 gl.endTransformFeedback();
3873 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed.");
3875 /* Retrieve data and check if it is correct. */
3877 (glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*offset*/,
3878 sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT);
3879 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
3881 for (size_t i = 0; i < 4; ++i)
3883 if (fabs(ptrTF_data_f[i] - expected_geom_results[i]) >= epsilon)
3890 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
3891 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
3893 ptrTF_data_f = NULL;
3900 /* Deactivate Geometry Shader Program Object from Program Pipeline Object. */
3901 gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, 0 /* program */);
3902 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed.");
3904 /* Second pass - only Vertex Shader Program On. */
3905 gl.beginTransformFeedback(GL_POINTS);
3906 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed.");
3908 gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/);
3909 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call(s) failed.");
3911 gl.endTransformFeedback();
3912 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed.");
3914 gl.disable(GL_RASTERIZER_DISCARD);
3915 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed.");
3917 /* Retrieve data and check if it is correct. */
3919 (glw::GLuint*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*offset*/,
3920 sizeof(glw::GLuint) * 4 /* four float vector components */, GL_MAP_READ_BIT);
3921 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
3923 for (size_t i = 0; i < 4; ++i)
3925 if (ptrTF_data_ui[i] != expected_vertex_results[i])
3932 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
3933 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
3935 ptrTF_data_ui = NULL;
3940 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3944 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3952 * @param context Test context
3953 * @param extParams Not used.
3954 * @param name Test case's name
3955 * @param description Test case's description
3957 GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives(
3958 Context& context, const ExtParameters& extParams, const char* name, const char* description)
3959 : TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_tfbo_id(0)
3965 /** Deinitializes GLES objects created during the test. */
3966 void GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::deinit()
3968 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3972 gl.deleteShader(m_fs_id);
3978 gl.deleteShader(m_gs_id);
3984 gl.deleteProgram(m_po_id);
3990 gl.deleteBuffers(1, &m_tfbo_id);
3996 gl.deleteVertexArrays(1, &m_vao_id);
4002 gl.deleteShader(m_vs_id);
4006 /* Release base class */
4007 TestCaseBase::deinit();
4010 /** Executes the test.
4012 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
4013 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
4014 * Note the function throws exception should an error occur!
4016 tcu::TestNode::IterateResult GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::iterate()
4018 /* Define Geometry Shader for purpose of this test. */
4019 const char* gs_code = "${VERSION}\n"
4020 "${GEOMETRY_SHADER_REQUIRE}\n"
4022 "layout (lines) in;\n"
4023 "layout (triangle_strip, max_vertices = 3) out;\n"
4025 "out vec4 out_gs_1;\n"
4029 " out_gs_1 = vec4(4.0, 3.0, 2.0, 1.0);\n"
4031 " gl_Position = vec4(0, 0, 0, 1);\n"
4034 " gl_Position = vec4(1, 0, 0, 1);\n"
4037 " gl_Position = vec4(1, 1, 0, 1);\n"
4043 bool has_shader_compilation_failed = true;
4045 glw::GLenum error = GL_NO_ERROR;
4047 /* This test should only run if EXT_geometry_shader is supported. */
4048 if (!m_is_geometry_shader_extension_supported)
4050 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
4053 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4055 /* Create program object. */
4056 m_po_id = gl.createProgram();
4057 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
4059 /* Specify output variables to be captured. */
4060 const char* tf_varyings[] = { "out_gs_1" };
4062 gl.transformFeedbackVaryings(m_po_id, 1 /*count*/, tf_varyings, GL_INTERLEAVED_ATTRIBS);
4063 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
4065 /* Create shader objects. */
4066 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
4067 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
4068 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
4069 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
4071 /* Try to link the test program object */
4072 std::string fs_code_specialized = specializeShader(1, &dummy_fs_code);
4073 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
4075 std::string gs_code_specialized = specializeShader(1, &gs_code);
4076 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
4078 std::string vs_code_specialized = specializeShader(1, &dummy_vs_code);
4079 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
4081 if (!TestCaseBase::buildProgram(m_po_id, m_fs_id, 1, /* n_sh1_body_parts */
4082 &fs_code_specialized_raw, m_gs_id, 1, /* n_sh2_body_parts */
4083 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh3_body_parts */
4084 &vs_code_specialized_raw, &has_shader_compilation_failed))
4086 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed whereas a success was expected."
4087 << tcu::TestLog::EndMessage;
4093 /* Create Vertex Array Object. */
4094 gl.genVertexArrays(1, &m_vao_id);
4095 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed.");
4097 gl.bindVertexArray(m_vao_id);
4098 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed.");
4100 /* Create Buffer Object for Transform Feedback data. */
4101 gl.genBuffers(1, &m_tfbo_id);
4102 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");
4104 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
4105 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");
4107 gl.bufferData(GL_ARRAY_BUFFER,
4108 sizeof(glw::GLfloat) * 4 * 3 /* capture 4 float vector components times 3 triangle vertices */, NULL,
4110 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed.");
4112 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id);
4113 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed.");
4115 /* Turn on program object. */
4116 gl.useProgram(m_po_id);
4117 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed.");
4119 gl.enable(GL_RASTERIZER_DISCARD);
4120 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed.");
4122 gl.beginTransformFeedback(GL_LINES);
4123 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed.");
4125 gl.drawArrays(GL_TRIANGLES, 0 /*first*/, 3 /*count*/);
4127 error = gl.getError();
4129 if (error != GL_INVALID_OPERATION)
4133 m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPEARATION was generated."
4134 << tcu::TestLog::EndMessage;
4137 gl.endTransformFeedback();
4138 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed.");
4140 gl.disable(GL_RASTERIZER_DISCARD);
4141 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed.");
4147 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4151 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4159 * @param context Test context
4160 * @param extParams Not used.
4161 * @param name Test case's name
4162 * @param description Test case's description
4164 GeometryShaderDrawCallsWhileTFPaused::GeometryShaderDrawCallsWhileTFPaused(Context& context,
4165 const ExtParameters& extParams,
4166 const char* name, const char* description)
4167 : TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_tfbo_id(0)
4173 /** Deinitializes GLES objects created during the test. */
4174 void GeometryShaderDrawCallsWhileTFPaused::deinit()
4176 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4180 gl.deleteShader(m_fs_id);
4186 gl.deleteShader(m_gs_id);
4190 for (int i = 0; i < 15 /* All combinations of possible inputs and outputs in GS */; ++i)
4192 if (m_po_ids[i] != 0)
4194 gl.deleteProgram(m_po_ids[i]);
4201 gl.deleteBuffers(1, &m_tfbo_id);
4207 gl.deleteVertexArrays(1, &m_vao_id);
4213 gl.deleteShader(m_vs_id);
4217 /* Release base class */
4218 TestCaseBase::deinit();
4221 /** Executes the test.
4223 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
4224 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
4225 * Note the function throws exception should an error occur!
4227 tcu::TestNode::IterateResult GeometryShaderDrawCallsWhileTFPaused::iterate()
4229 /* Define 15 (all combinations of possible inputs and outputs in geometry shader) Geometry Shaders for purpose of this test. */
4230 const std::string gs_inputs[] = { "points", "lines", "lines_adjacency", "triangles", "triangles_adjacency" };
4231 const std::string gs_outputs[] = { "points", "line_strip", "triangle_strip" };
4232 const std::string gs_max_output_vertices[] = { "1", "2", "3" };
4234 const unsigned short number_of_combinations =
4235 (sizeof(gs_inputs) / sizeof(gs_inputs[0]) * (sizeof(gs_outputs) / sizeof(gs_outputs[0])));
4237 std::string gs_codes[number_of_combinations];
4238 glw::GLenum errorCode;
4240 for (size_t i = 0; i < (sizeof(gs_inputs) / sizeof(gs_inputs[0])) /*5 possible GS inputs*/; ++i)
4242 for (size_t j = 0; j < (sizeof(gs_outputs) / sizeof(gs_outputs[0])) /*3 possible GS outputs*/; ++j)
4244 /* This shader will not emit primitives for anything but points.
4245 * We do so, because we just need to make sure that, while transform feedback
4246 * is paused, all draw calls executed with an active program object which
4247 * includes a geometry shader, are valid.
4249 gs_codes[j + 3 * i] = "${VERSION}\n"
4250 "${GEOMETRY_SHADER_REQUIRE}\n"
4253 gs_inputs[i] + ") in;\n"
4255 gs_outputs[j] + ", max_vertices = " + gs_max_output_vertices[j] +
4258 "out vec2 out_gs_1;\n"
4262 " out_gs_1 = vec2(1.0, 2.0);\n"
4263 " gl_Position = vec4(0, 0, 0, 1);\n"
4269 bool has_shader_compilation_failed = true;
4271 const glw::GLuint tf_modes[3] = { GL_POINTS, GL_LINES, GL_TRIANGLES };
4272 const glw::GLuint draw_call_modes[5] = { GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES,
4273 GL_TRIANGLES_ADJACENCY };
4275 /* This test should only run if EXT_geometry_shader is supported. */
4276 if (!m_is_geometry_shader_extension_supported)
4278 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
4281 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4283 /* Create program objects. */
4284 for (int i = 0; i < number_of_combinations; ++i)
4286 m_po_ids[i] = gl.createProgram();
4288 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
4290 /* Specify output variables to be captured. */
4291 const char* tf_varyings[] = { "out_gs_1" };
4293 for (int i = 0; i < number_of_combinations; ++i)
4295 gl.transformFeedbackVaryings(m_po_ids[i], 1 /*count*/, tf_varyings, GL_INTERLEAVED_ATTRIBS);
4297 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
4299 /* Create shader objects. */
4300 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
4301 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
4302 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
4303 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
4305 /* Try to link the test program object */
4306 std::string fs_code_specialized = specializeShader(1, &dummy_fs_code);
4307 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
4309 std::string vs_code_specialized = specializeShader(1, &dummy_vs_code);
4310 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
4312 for (int i = 0; i < number_of_combinations; ++i)
4314 const char* gs_code = gs_codes[i].c_str();
4315 std::string gs_code_specialized = specializeShader(1, &gs_code);
4316 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
4318 if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */
4319 &fs_code_specialized_raw, m_gs_id, 1, /* n_sh2_body_parts */
4320 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh3_body_parts */
4321 &vs_code_specialized_raw, &has_shader_compilation_failed))
4323 m_testCtx.getLog() << tcu::TestLog::Message
4324 << "Program object linking failed whereas a success was expected."
4325 << tcu::TestLog::EndMessage;
4336 /* Create Vertex Array Object. */
4337 gl.genVertexArrays(1, &m_vao_id);
4338 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed.");
4340 gl.bindVertexArray(m_vao_id);
4341 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed.");
4343 /* Create Buffer Object for Transform Feedback data. */
4344 gl.genBuffers(1, &m_tfbo_id);
4345 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");
4347 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
4348 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");
4350 gl.bufferData(GL_ARRAY_BUFFER,
4351 sizeof(glw::GLfloat) * 2 * 3 /* capture 2 float vector components times 3 triangle vertices */, NULL,
4353 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed.");
4355 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id);
4356 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed.");
4358 gl.enable(GL_RASTERIZER_DISCARD);
4359 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed.");
4361 for (int i = 0; i < 3 /* number of TF modes */ && result; ++i)
4363 for (int j = 0; j < 5 /*number of draw call modes*/ && result; ++j)
4365 for (int k = 0; k < 3 /* number of output GS primitive types */; ++k)
4367 /* Turn on program object. */
4368 gl.useProgram(m_po_ids[k + 3 * j]);
4369 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed.");
4371 gl.beginTransformFeedback(tf_modes[i]);
4372 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed.");
4374 gl.pauseTransformFeedback();
4375 GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback() call(s) failed.");
4377 gl.drawArrays(draw_call_modes[j], 0 /*first*/, 3 /*count*/);
4378 errorCode = gl.getError();
4380 gl.resumeTransformFeedback();
4381 GLU_EXPECT_NO_ERROR(gl.getError(), "glResumeTransformFeedback() call(s) failed.");
4383 gl.endTransformFeedback();
4384 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed.");
4386 /* If draw call fails stop test execution. */
4387 if (GL_NO_ERROR != errorCode)
4389 m_testCtx.getLog() << tcu::TestLog::Message
4390 << "glDrawArrays() call generated an error while transform feedback was paused."
4391 << tcu::TestLog::EndMessage;
4400 gl.disable(GL_RASTERIZER_DISCARD);
4401 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed.");
4407 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4411 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4417 } // namespace glcts