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 /* Retrieve GL_MAX_IMAGE_UNITS pname value */
1558 glw::GLint m_gl_max_image_units_value = 0;
1559 gl.getIntegerv(GL_MAX_IMAGE_UNITS, &m_gl_max_image_units_value);
1560 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_IMAGE_UNITS pname");
1562 /* Check if m_gl_max_geometry_image_uniforms_value is less than or equal zero. */
1563 if (m_gl_max_geometry_image_uniforms_ext_value <= 0)
1565 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT query value "
1566 << "[" << m_gl_max_geometry_image_uniforms_ext_value
1568 " is less than or equal zero. Image uniforms in Geometry Shader"
1569 " are not supported."
1570 << tcu::TestLog::EndMessage;
1572 if (m_gl_max_geometry_image_uniforms_ext_value == 0)
1574 throw tcu::NotSupportedError("GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT is 0");
1583 /* Check if m_gl_max_image_units_value is less than m_gl_max_geometry_image_uniforms_value. */
1584 if (m_gl_max_image_units_value < m_gl_max_geometry_image_uniforms_ext_value)
1586 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT query value "
1587 << "[" << m_gl_max_geometry_image_uniforms_ext_value
1589 " is greater than GL_MAX_IMAGE_UNITS query value "
1591 << m_gl_max_image_units_value << "]." << tcu::TestLog::EndMessage;
1597 /* Create a program object. */
1598 m_po_id = gl.createProgram();
1599 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1601 /* Create shader objects. */
1602 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1603 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1604 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1606 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1608 /* Configure which outputs should be captured by Transform Feedback. */
1609 gl.transformFeedbackVaryings(m_po_id, 1 /* varyings count */, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
1611 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
1613 /* Try to link the test program object */
1614 fs_code_specialized = specializeShader(1, &dummy_fs_code);
1615 fs_code_specialized_raw = fs_code_specialized.c_str();
1617 gs_code_specialized = getGSCode();
1618 gs_code_specialized_raw = gs_code_specialized.c_str();
1620 vs_code_specialized = specializeShader(1, &dummy_vs_code);
1621 vs_code_specialized_raw = vs_code_specialized.c_str();
1623 if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */
1624 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1625 &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1626 &fs_code_specialized_raw, &has_shader_compilation_failed))
1628 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
1635 gl.useProgram(m_po_id);
1636 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
1638 /* Allocate memory for m_max_image_units_value Texture Objects. */
1639 m_texture_ids = new glw::GLuint[m_gl_max_geometry_image_uniforms_ext_value];
1641 /* Generate m_max_image_units_value Texture Objects. */
1642 gl.genTextures(m_gl_max_geometry_image_uniforms_ext_value, m_texture_ids);
1643 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
1645 /* Set GL_PACK_ALIGNMENT to 1. */
1646 gl.pixelStorei(GL_PACK_ALIGNMENT, 1);
1647 GLU_EXPECT_NO_ERROR(gl.getError(), "glPixelStorei() call failed for GL_PACK_ALIGNMENT pname.");
1649 /* Bind integer 2D texture objects of resolution 1x1 to image units. */
1650 for (glw::GLint n_img = 0; n_img < (m_gl_max_geometry_image_uniforms_ext_value); ++n_img)
1652 glw::GLint texture = m_texture_ids[n_img];
1653 glw::GLint value = n_img + 1;
1655 gl.bindTexture(GL_TEXTURE_2D, texture);
1656 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
1658 gl.texStorage2D(GL_TEXTURE_2D, 1 /*levels*/, GL_R32I, 1 /*width*/, 1 /*height*/);
1659 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
1661 gl.texSubImage2D(GL_TEXTURE_2D, 0 /*level*/, 0 /*xoffset*/, 0 /*yoffset*/, 1 /*width*/, 1 /*height*/,
1662 GL_RED_INTEGER, GL_INT, &value);
1663 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexSubImage2D() call failed.");
1665 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1666 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri() call failed.");
1668 gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1669 GLU_EXPECT_NO_ERROR(gl.getError(), "texParameteri() call failed.");
1671 gl.bindImageTexture(n_img, texture, 0 /*level*/, GL_FALSE /*is layered?*/, 0 /*layer*/, GL_READ_ONLY, GL_R32I);
1672 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindImageTexture() call failed.");
1675 /* Configure VAO. */
1676 gl.genVertexArrays(1, &m_vao_id);
1677 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
1679 gl.bindVertexArray(m_vao_id);
1680 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
1682 /* Create a Buffer Object for Transform Feedback's outputs. */
1683 gl.genBuffers(1, &m_tfbo_id);
1684 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
1686 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
1687 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
1689 gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4 /* four float vector components */, NULL, GL_STATIC_READ);
1690 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
1692 /* Bind Buffer Object m_tfbo_id to GL_TRANSFORM_FEEDBACK_BUFFER binding point. */
1693 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_tfbo_id);
1694 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
1696 /* Disable rasterization and make a draw call. After that, turn on rasterization. */
1697 gl.enable(GL_RASTERIZER_DISCARD);
1698 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed for GL_RASTERIZER_DISCARD pname.");
1700 gl.beginTransformFeedback(GL_POINTS);
1701 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
1703 gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/);
1704 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
1706 gl.endTransformFeedback();
1707 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
1709 gl.disable(GL_RASTERIZER_DISCARD);
1710 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed for GL_RASTERIZER_DISCARD pname.");
1712 /* Retrieve value from Transform Feedback. */
1714 ptr = (glw::GLfloat*)gl.mapBufferRange(
1715 GL_ARRAY_BUFFER, 0, sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT);
1717 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
1719 counter = int(ptr[0] + 0.5f);
1721 gl.unmapBuffer(GL_ARRAY_BUFFER);
1722 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
1724 /* Calculate expected value. */
1725 expectedValue = m_gl_max_geometry_image_uniforms_ext_value * (m_gl_max_geometry_image_uniforms_ext_value + 1) / 2;
1727 if (counter != expectedValue)
1735 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1739 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1747 * @param context Test context
1748 * @param extParams Not used.
1749 * @param name Test case's name
1750 * @param description Test case's description
1752 GeometryShaderMaxShaderStorageBlocksTest::GeometryShaderMaxShaderStorageBlocksTest(Context& context,
1753 const ExtParameters& extParams,
1755 const char* description)
1756 : TestCaseBase(context, extParams, name, description)
1758 , m_gl_max_geometry_shader_storage_blocks_ext_value(0)
1768 /** Deinitializes GLES objects created during the test. */
1769 void GeometryShaderMaxShaderStorageBlocksTest::deinit()
1771 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1775 gl.deleteShader(m_fs_id);
1781 gl.deleteShader(m_gs_id);
1787 gl.deleteProgram(m_po_id);
1793 gl.deleteBuffers(1, &m_ssbo_id);
1799 gl.deleteBuffers(1, &m_tfbo_id);
1805 gl.deleteVertexArrays(1, &m_vao_id);
1811 gl.deleteShader(m_vs_id);
1815 /* Release base class */
1816 TestCaseBase::deinit();
1819 /* Retrieves test-specific geometry shader source code.
1821 * @return Requested string.
1823 std::string GeometryShaderMaxShaderStorageBlocksTest::getGSCode()
1825 std::stringstream code_sstream;
1828 code_sstream << "${VERSION}\n"
1829 "${GEOMETRY_SHADER_REQUIRE}\n"
1831 "layout (points) in;\n"
1832 "layout (points, max_vertices = 1) out;\n"
1834 "int counter = 0;\n"
1837 for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb)
1839 code_sstream << "layout(binding = " << n_ssb << ") buffer ssb" << n_ssb << " \n{\n"
1841 << "} S_SSB" << n_ssb << ";\n\n";
1844 code_sstream << "\n"
1848 for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb)
1850 code_sstream << " counter += S_SSB" << n_ssb << ".value++;\n";
1853 code_sstream << "\n"
1854 " gl_Position = vec4(float(counter), 0.0, 0.0, 1.0);\n"
1858 /* Form a specialized version of the GS source code */
1859 std::string gs_code = code_sstream.str();
1860 const char* gs_code_raw = gs_code.c_str();
1861 std::string gs_code_specialized = specializeShader(1 /* parts */, &gs_code_raw);
1863 return gs_code_specialized;
1866 /** Executes the test.
1868 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
1869 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
1870 * Note the function throws exception should an error occur!
1872 tcu::TestNode::IterateResult GeometryShaderMaxShaderStorageBlocksTest::iterate()
1874 glw::GLint counter = 0;
1875 glw::GLint expectedValue = 0;
1876 const glw::GLchar* feedbackVaryings[] = { "gl_Position" };
1877 bool has_shader_compilation_failed = true;
1878 const glw::GLfloat initial_buffer_data[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
1879 glw::GLint int_alignment = 0;
1880 const glw::GLint int_size = sizeof(glw::GLint);
1881 glw::GLint* ptrSSBO_data = DE_NULL;
1882 glw::GLfloat* ptrTF_data = DE_NULL;
1884 glw::GLint ssbo_alignment = 0;
1885 glw::GLint* ssbo_data = DE_NULL;
1886 glw::GLint ssbo_data_size = 0;
1888 std::string fs_code_specialized = "";
1889 const char* fs_code_specialized_raw = DE_NULL;
1890 std::string gs_code_specialized = "";
1891 const char* gs_code_specialized_raw = DE_NULL;
1892 std::string vs_code_specialized = "";
1893 const char* vs_code_specialized_raw = DE_NULL;
1895 /* This test should only run if EXT_geometry_shader is supported. */
1896 if (!m_is_geometry_shader_extension_supported)
1898 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
1901 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1903 /* Retrieve GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT pname value */
1904 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_STORAGE_BLOCKS,
1905 &m_gl_max_geometry_shader_storage_blocks_ext_value);
1906 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT pname");
1908 /* Retrieve GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS pname value */
1909 glw::GLint m_gl_max_shader_storage_buffer_bindings_value = 0;
1911 gl.getIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &m_gl_max_shader_storage_buffer_bindings_value);
1912 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS pname");
1914 /* Check if m_gl_max_shader_storage_blocks_value is less than or equal zero. */
1915 if (m_gl_max_geometry_shader_storage_blocks_ext_value <= 0)
1917 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT query value "
1918 << "[" << m_gl_max_geometry_shader_storage_blocks_ext_value
1920 " is less than or equal zero. Shader Storage Blocks"
1921 " in Geometry Shader are not supported."
1922 << tcu::TestLog::EndMessage;
1924 if (m_gl_max_geometry_shader_storage_blocks_ext_value == 0)
1926 throw tcu::NotSupportedError("GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT is 0");
1935 /* Check if m_gl_max_shader_storage_buffer_bindings_value is less than m_gl_max_shader_storage_blocks_value. */
1936 if (m_gl_max_shader_storage_buffer_bindings_value < m_gl_max_geometry_shader_storage_blocks_ext_value)
1938 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT query value "
1939 << "[" << m_gl_max_geometry_shader_storage_blocks_ext_value
1941 " is greater than GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS query value "
1943 << m_gl_max_shader_storage_buffer_bindings_value << "]." << tcu::TestLog::EndMessage;
1949 /* Create a program object. */
1950 m_po_id = gl.createProgram();
1951 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
1953 /* Create shader objects. */
1954 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
1955 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
1956 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
1958 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
1960 /* Configure which outputs should be captured by Transform Feedback. */
1961 gl.transformFeedbackVaryings(m_po_id, 1 /* varyings count */, feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
1963 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call failed.");
1965 /* Try to link the test program object */
1966 fs_code_specialized = specializeShader(1, &dummy_fs_code);
1967 fs_code_specialized_raw = fs_code_specialized.c_str();
1969 gs_code_specialized = getGSCode();
1970 gs_code_specialized_raw = gs_code_specialized.c_str();
1972 vs_code_specialized = specializeShader(1, &dummy_vs_code);
1973 vs_code_specialized_raw = vs_code_specialized.c_str();
1975 if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */
1976 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
1977 &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
1978 &fs_code_specialized_raw, &has_shader_compilation_failed))
1980 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
1986 /* Prepare data for Shader Storage Buffer Object. */
1987 gl.getIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssbo_alignment);
1988 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() call failed.");
1990 int_alignment = ssbo_alignment / int_size;
1991 ssbo_data_size = m_gl_max_geometry_shader_storage_blocks_ext_value * ssbo_alignment;
1992 ssbo_data = new glw::GLint[ssbo_data_size];
1994 if ((ssbo_alignment % int_size) != 0)
1996 m_testCtx.getLog() << tcu::TestLog::Message << "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT query value "
1998 << ssbo_alignment << "]"
1999 "divide with remainder by the size of GLint "
2001 << int_size << "]" << tcu::TestLog::EndMessage;
2007 for (int i = 0; i < m_gl_max_geometry_shader_storage_blocks_ext_value; ++i)
2009 ssbo_data[i * int_alignment] = i + 1;
2012 /* Create Shader Storage Buffer Object. */
2013 gl.genBuffers(1, &m_ssbo_id);
2014 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2016 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo_id);
2017 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname.");
2019 gl.bufferData(GL_SHADER_STORAGE_BUFFER, ssbo_data_size, ssbo_data, GL_DYNAMIC_COPY);
2020 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2022 /* Free unused memory. */
2026 /* Bind specific m_ssbo_id buffer region to a specific Shader Storage Buffer binding point. */
2027 for (glw::GLint n_ssb = 0; n_ssb < (m_gl_max_geometry_shader_storage_blocks_ext_value); ++n_ssb)
2029 glw::GLuint offset = n_ssb * ssbo_alignment;
2031 gl.bindBufferRange(GL_SHADER_STORAGE_BUFFER, n_ssb /*binding index*/, m_ssbo_id, offset, int_size);
2032 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed.");
2035 /* Configure VAO. */
2036 gl.genVertexArrays(1, &m_vao_id);
2037 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2039 gl.bindVertexArray(m_vao_id);
2040 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2042 /* Create a Buffer Object for Transform Feedback's outputs. */
2043 gl.genBuffers(1, &m_tfbo_id);
2044 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2046 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
2047 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
2049 gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4 /* four float vector components */, initial_buffer_data,
2051 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2053 /* Bind Buffer Object m_tfbo_id to GL_TRANSFORM_FEEDBACK_BUFFER binding point. */
2054 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id);
2055 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call failed.");
2058 gl.useProgram(m_po_id);
2059 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2061 /* Disable rasterization and make a draw call. After that, turn on rasterization. */
2062 gl.enable(GL_RASTERIZER_DISCARD);
2063 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call failed for GL_RASTERIZER_DISCARD pname.");
2065 gl.beginTransformFeedback(GL_POINTS);
2066 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call failed.");
2068 gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/);
2069 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
2071 gl.endTransformFeedback();
2072 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call failed.");
2074 gl.disable(GL_RASTERIZER_DISCARD);
2075 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call failed for GL_RASTERIZER_DISCARD pname.");
2077 /* Retrieve value from Transform Feedback. */
2078 ptrTF_data = (glw::GLfloat*)gl.mapBufferRange(
2079 GL_ARRAY_BUFFER, 0 /*offset*/, sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT);
2080 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
2082 counter = int(ptrTF_data[0] + 0.5f);
2084 gl.unmapBuffer(GL_ARRAY_BUFFER);
2085 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
2089 /* Retrieve values from Shader Storage Buffer Object. */
2091 (glw::GLint*)gl.mapBufferRange(GL_SHADER_STORAGE_BUFFER, 0 /*offset*/, ssbo_data_size, GL_MAP_READ_BIT);
2092 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
2094 for (int i = 0; i < m_gl_max_geometry_shader_storage_blocks_ext_value; ++i)
2096 if (ptrSSBO_data[i * int_alignment] != i + 2)
2100 m_testCtx.getLog() << tcu::TestLog::Message << "Value read from Shader Storage Buffer "
2102 << ptrSSBO_data[i * int_alignment] << "] "
2105 << i * int_alignment << "]"
2106 "is not equal to expected value "
2108 << i + 2 << "]" << tcu::TestLog::EndMessage;
2114 gl.unmapBuffer(GL_SHADER_STORAGE_BUFFER);
2115 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
2117 ptrSSBO_data = NULL;
2119 /* Calculate expected value. */
2121 m_gl_max_geometry_shader_storage_blocks_ext_value * (m_gl_max_geometry_shader_storage_blocks_ext_value + 1) / 2;
2123 if (counter != expectedValue)
2131 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2135 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2143 * @param context Test context
2144 * @param extParams Not used.
2145 * @param name Test case's name
2146 * @param description Test case's description
2148 GeometryShaderMaxAtomicCountersTest::GeometryShaderMaxAtomicCountersTest(Context& context,
2149 const ExtParameters& extParams,
2150 const char* name, const char* description)
2151 : TestCaseBase(context, extParams, name, description)
2154 , m_gl_max_geometry_atomic_counters_ext_value(0)
2162 /** Deinitializes GLES objects created during the test. */
2163 void GeometryShaderMaxAtomicCountersTest::deinit()
2165 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2169 gl.deleteBuffers(1, &m_acbo_id);
2175 gl.deleteShader(m_fs_id);
2181 gl.deleteShader(m_gs_id);
2187 gl.deleteProgram(m_po_id);
2193 gl.deleteVertexArrays(1, &m_vao_id);
2199 gl.deleteShader(m_vs_id);
2203 /* Release base class */
2204 TestCaseBase::deinit();
2207 /* Retrieves test-specific geometry shader source code.
2209 * @return Requested string.
2211 std::string GeometryShaderMaxAtomicCountersTest::getGSCode()
2213 std::stringstream code_sstream;
2216 code_sstream << "${VERSION}\n"
2217 "${GEOMETRY_SHADER_REQUIRE}\n"
2219 "layout (points) in;\n"
2220 "layout (points, max_vertices = 1) out;\n"
2222 "uniform int n_loop_iterations;\n"
2223 "flat in int vertex_id[];\n"
2226 code_sstream << "layout(binding = 0) uniform atomic_uint acs[" << m_gl_max_geometry_atomic_counters_ext_value
2231 " for (int counter_id = 1;\n"
2232 " counter_id <= n_loop_iterations;\n"
2235 " if ((vertex_id[0] % counter_id) == 0)\n"
2237 " atomicCounterIncrement(acs[counter_id - 1]);\n"
2241 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2245 /* Form a specialized version of the GS source code */
2246 std::string gs_code = code_sstream.str();
2247 const char* gs_code_raw = gs_code.c_str();
2248 std::string gs_code_specialized = specializeShader(1, /* parts */ &gs_code_raw);
2250 return gs_code_specialized;
2253 /** Executes the test.
2255 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2256 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2257 * Note the function throws exception should an error occur!
2259 tcu::TestNode::IterateResult GeometryShaderMaxAtomicCountersTest::iterate()
2261 /* Define Vertex Shader's code for the purpose of this test. */
2262 const char* vs_code = "${VERSION}\n"
2264 "flat out int vertex_id;\n"
2268 " vertex_id = gl_VertexID;\n"
2269 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2272 bool has_shader_compilation_failed = true;
2273 glw::GLuint* initial_ac_data = DE_NULL;
2274 const unsigned int n_draw_call_vertices = 4;
2275 glw::GLint n_loop_iterations_uniform_location = -1;
2276 glw::GLuint* ptrACBO_data = DE_NULL;
2279 std::string fs_code_specialized = "";
2280 const char* fs_code_specialized_raw = DE_NULL;
2281 std::string gs_code_specialized = "";
2282 const char* gs_code_specialized_raw = DE_NULL;
2283 std::string vs_code_specialized = "";
2284 const char* vs_code_specialized_raw = DE_NULL;
2286 /* This test should only run if EXT_geometry_shader is supported. */
2287 if (!m_is_geometry_shader_extension_supported)
2289 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2292 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2294 /* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname value */
2295 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &m_gl_max_geometry_atomic_counters_ext_value);
2296 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT pname");
2298 /* Check if m_gl_max_atomic_counters_value is less than or equal zero. */
2299 if (m_gl_max_geometry_atomic_counters_ext_value <= 0)
2301 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT query value "
2302 << "[" << m_gl_max_geometry_atomic_counters_ext_value
2304 " is less than or equal to zero. Atomic Counters"
2305 " in Geometry Shader are not supported."
2306 << tcu::TestLog::EndMessage;
2308 if (m_gl_max_geometry_atomic_counters_ext_value == 0)
2310 throw tcu::NotSupportedError("GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT is 0");
2319 /* Create a program object. */
2320 m_po_id = gl.createProgram();
2321 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2323 /* Create shader objects. */
2324 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2325 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2326 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2328 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2330 /* Try to link the test program object */
2331 fs_code_specialized = specializeShader(1, &dummy_fs_code);
2332 fs_code_specialized_raw = fs_code_specialized.c_str();
2334 gs_code_specialized = getGSCode();
2335 gs_code_specialized_raw = gs_code_specialized.c_str();
2337 vs_code_specialized = specializeShader(1, &vs_code);
2338 vs_code_specialized_raw = vs_code_specialized.c_str();
2340 if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */
2341 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
2342 &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
2343 &fs_code_specialized_raw, &has_shader_compilation_failed))
2345 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
2351 /* Create Atomic Counter Buffer Objects. */
2352 gl.genBuffers(1, &m_acbo_id);
2353 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2355 /* Prepare initial data - zeroes - to fill the Atomic Counter Buffer Object. */
2356 initial_ac_data = new glw::GLuint[m_gl_max_geometry_atomic_counters_ext_value];
2357 memset(initial_ac_data, 0, sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value);
2359 gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_id);
2360 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname.");
2362 gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value, NULL,
2364 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2366 gl.bufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/,
2367 sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value,
2368 initial_ac_data /*initialize with zeroes*/);
2369 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferSubData() call failed.");
2371 gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0 /*binding index*/, m_acbo_id /*buffer*/);
2372 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed.");
2374 /* Configure VAO. */
2375 gl.genVertexArrays(1, &m_vao_id);
2376 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2378 gl.bindVertexArray(m_vao_id);
2379 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2382 n_loop_iterations_uniform_location = gl.getUniformLocation(m_po_id, "n_loop_iterations");
2384 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call failed.");
2385 if (n_loop_iterations_uniform_location == -1)
2387 TCU_FAIL("n_loop_iterations uniform is considered inactive");
2391 gl.useProgram(m_po_id);
2392 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2394 gl.uniform1i(n_loop_iterations_uniform_location, m_gl_max_geometry_atomic_counters_ext_value);
2395 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i() call failed.");
2398 /* Issue the draw call */
2399 gl.drawArrays(GL_POINTS, 0, n_draw_call_vertices);
2400 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
2402 /* Retrieve values from Atomic Counter Buffer Objects and check if these values are valid. */
2403 ptrACBO_data = (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/,
2404 sizeof(glw::GLuint) * m_gl_max_geometry_atomic_counters_ext_value,
2406 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
2408 for (glw::GLint n_ac = 0; n_ac < m_gl_max_geometry_atomic_counters_ext_value; ++n_ac)
2410 unsigned int expected_value = 0;
2412 for (unsigned int n_draw_call_vertex = 0; n_draw_call_vertex < n_draw_call_vertices; ++n_draw_call_vertex)
2414 if ((n_draw_call_vertex % (n_ac + 1)) == 0)
2420 if (ptrACBO_data[n_ac] != expected_value)
2427 gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2428 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
2430 ptrACBO_data = NULL;
2435 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2439 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2447 * @param context Test context
2448 * @param extParams Not used.
2449 * @param name Test case's name
2450 * @param description Test case's description
2452 GeometryShaderMaxAtomicCounterBuffersTest::GeometryShaderMaxAtomicCounterBuffersTest(Context& context,
2453 const ExtParameters& extParams,
2455 const char* description)
2456 : TestCaseBase(context, extParams, name, description)
2459 , m_gl_max_atomic_counter_buffer_bindings_value(0)
2460 , m_gl_max_geometry_atomic_counter_buffers_ext_value(0)
2468 /** Deinitializes GLES objects created during the test. */
2469 void GeometryShaderMaxAtomicCounterBuffersTest::deinit()
2471 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2473 if (m_acbo_ids != NULL)
2475 if (m_gl_max_geometry_atomic_counter_buffers_ext_value > 0)
2477 gl.deleteBuffers(m_gl_max_geometry_atomic_counter_buffers_ext_value, m_acbo_ids);
2479 delete[] m_acbo_ids;
2486 gl.deleteShader(m_fs_id);
2492 gl.deleteShader(m_gs_id);
2498 gl.deleteProgram(m_po_id);
2504 gl.deleteVertexArrays(1, &m_vao_id);
2510 gl.deleteShader(m_vs_id);
2514 /* Release base class */
2515 TestCaseBase::deinit();
2518 /* Retrieves test-specific geometry shader source code.
2520 * @return Requested string.
2522 std::string GeometryShaderMaxAtomicCounterBuffersTest::getGSCode()
2524 std::stringstream code_sstream;
2527 code_sstream << "${VERSION}\n"
2528 "${GEOMETRY_SHADER_REQUIRE}\n"
2530 "layout (points) in;\n"
2531 "layout (points, max_vertices = 1) out;\n"
2533 "flat in int vertex_id[];\n"
2536 for (glw::GLint n_ac = 0; n_ac < (m_gl_max_geometry_atomic_counter_buffers_ext_value); ++n_ac)
2538 code_sstream << "layout(binding = " << n_ac << ") uniform atomic_uint ac" << n_ac << ";\n";
2541 code_sstream << "\n"
2544 " for(int counter_id = 1; counter_id <= "
2545 << m_gl_max_geometry_atomic_counter_buffers_ext_value
2546 << "; ++counter_id)\n"
2548 " if((vertex_id[0] % counter_id) == 0)\n"
2551 for (glw::GLint n_ac = 0; n_ac < (m_gl_max_geometry_atomic_counter_buffers_ext_value); ++n_ac)
2553 code_sstream << " atomicCounterIncrement(ac" << n_ac << ");\n";
2556 code_sstream << " }\n"
2559 code_sstream << "\n"
2560 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2564 /* Form a specialized version of the GS source code */
2565 std::string gs_code = code_sstream.str();
2566 const char* gs_code_raw = gs_code.c_str();
2567 std::string gs_code_specialized = specializeShader(1, /* parts */ &gs_code_raw);
2569 return gs_code_specialized;
2572 /** Executes the test.
2574 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2575 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2576 * Note the function throws exception should an error occur!
2578 tcu::TestNode::IterateResult GeometryShaderMaxAtomicCounterBuffersTest::iterate()
2580 /* Define Vertex Shader's code for the purpose of this test. */
2581 const char* vs_code = "${VERSION}\n"
2583 "flat out int vertex_id;\n"
2587 " vertex_id = gl_VertexID;\n"
2588 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
2591 unsigned int expected_value = 0;
2592 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2593 bool has_shader_compilation_failed = true;
2594 const glw::GLuint initial_ac_data = 0;
2595 const glw::GLuint number_of_indices = 128 * m_gl_max_geometry_atomic_counter_buffers_ext_value;
2598 std::string fs_code_specialized = "";
2599 const char* fs_code_specialized_raw = DE_NULL;
2600 std::string gs_code_specialized = "";
2601 const char* gs_code_specialized_raw = DE_NULL;
2602 std::string vs_code_specialized = "";
2603 const char* vs_code_specialized_raw = DE_NULL;
2605 /* This test should only run if EXT_geometry_shader is supported. */
2606 if (!m_is_geometry_shader_extension_supported)
2608 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2611 /* Retrieve GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname value */
2612 gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS,
2613 &m_gl_max_geometry_atomic_counter_buffers_ext_value);
2614 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT pname");
2616 /* Retrieve GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS pname value */
2617 gl.getIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &m_gl_max_atomic_counter_buffer_bindings_value);
2618 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS pname");
2620 /* Check if m_gl_max_geometry_atomic_counter_buffers_ext_value is less than or equal zero. */
2621 if (m_gl_max_geometry_atomic_counter_buffers_ext_value <= 0)
2623 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT query value "
2624 << "[" << m_gl_max_geometry_atomic_counter_buffers_ext_value
2626 " is less than or equal to zero. Atomic Counter Buffers"
2627 " are not supported."
2628 << tcu::TestLog::EndMessage;
2630 if (m_gl_max_geometry_atomic_counter_buffers_ext_value == 0)
2632 throw tcu::NotSupportedError("GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT is 0");
2641 /* Check if m_gl_max_atomic_counter_buffer_bindings_value is less than m_gl_max_shader_storage_blocks_value. */
2642 if (m_gl_max_atomic_counter_buffer_bindings_value < m_gl_max_geometry_atomic_counter_buffers_ext_value)
2644 m_testCtx.getLog() << tcu::TestLog::Message << "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT query value "
2645 << "[" << m_gl_max_geometry_atomic_counter_buffers_ext_value
2647 " is greater than GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS query value "
2649 << m_gl_max_atomic_counter_buffer_bindings_value << "]." << tcu::TestLog::EndMessage;
2655 /* Create a program object. */
2656 m_po_id = gl.createProgram();
2657 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2659 /* Create shader objects. */
2660 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2661 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2662 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
2664 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2666 /* Try to link the test program object */
2667 fs_code_specialized = specializeShader(1, &dummy_fs_code);
2668 fs_code_specialized_raw = fs_code_specialized.c_str();
2670 gs_code_specialized = getGSCode();
2671 gs_code_specialized_raw = gs_code_specialized.c_str();
2673 vs_code_specialized = specializeShader(1, &vs_code);
2674 vs_code_specialized_raw = vs_code_specialized.c_str();
2676 if (!TestCaseBase::buildProgram(m_po_id, m_gs_id, 1, /* n_sh1_body_parts */
2677 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh2_body_parts */
2678 &vs_code_specialized_raw, m_fs_id, 1, /* n_sh3_body_parts */
2679 &fs_code_specialized_raw, &has_shader_compilation_failed))
2681 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed." << tcu::TestLog::EndMessage;
2687 /* Create Atomic Counter Buffer Objects. */
2688 m_acbo_ids = new glw::GLuint[m_gl_max_geometry_atomic_counter_buffers_ext_value];
2690 gl.genBuffers(m_gl_max_geometry_atomic_counter_buffers_ext_value, m_acbo_ids);
2691 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call failed.");
2693 for (glw::GLint n_acb = 0; n_acb < m_gl_max_geometry_atomic_counter_buffers_ext_value; ++n_acb)
2695 gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_ids[n_acb]);
2696 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed for GL_SHADER_STORAGE_BUFFER pname.");
2698 gl.bufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(glw::GLuint), &initial_ac_data /*initialize with zeroes*/,
2700 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call failed.");
2702 gl.bindBufferBase(GL_ATOMIC_COUNTER_BUFFER, n_acb /*binding index*/, m_acbo_ids[n_acb] /*buffer*/);
2703 GLU_EXPECT_NO_ERROR(gl.getError(), "bindBufferRange() call failed.");
2706 /* Configure VAO. */
2707 gl.genVertexArrays(1, &m_vao_id);
2708 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2710 gl.bindVertexArray(m_vao_id);
2711 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2714 gl.useProgram(m_po_id);
2715 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
2717 gl.drawArrays(GL_POINTS, 0 /*starting index*/, number_of_indices);
2718 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
2720 /* Calculate expected value. */
2721 /* For each point being processed by Geometry Shader. */
2722 for (glw::GLuint vertex_id = 0; vertex_id < number_of_indices; ++vertex_id)
2724 /* And for each atomic counter ID. */
2725 for (int atomic_counter_id = 1; atomic_counter_id <= m_gl_max_geometry_atomic_counter_buffers_ext_value;
2726 ++atomic_counter_id)
2728 /* Check if (vertex_id % atomic_counter_id) == 0. If it is true, increment expected_value. */
2729 if (vertex_id % atomic_counter_id == 0)
2736 /* Retrieve values from Atomic Counter Buffer Objects and check if these values are valid. */
2737 for (glw::GLint n_acb = 0; n_acb < m_gl_max_geometry_atomic_counter_buffers_ext_value; ++n_acb)
2739 gl.bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_acbo_ids[n_acb]);
2740 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call failed.");
2742 glw::GLuint* ptrABO_data = (glw::GLuint*)gl.mapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0 /*offset*/,
2743 sizeof(glw::GLuint) /*length*/, GL_MAP_READ_BIT);
2744 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
2746 if (ptrABO_data[0] != expected_value)
2752 gl.unmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2753 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
2761 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2765 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2773 * @param context Test context
2774 * @param extParams Not used.
2775 * @param name Test case's name
2776 * @param description Test case's description
2778 GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest::
2779 GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest(Context& context, const ExtParameters& extParams,
2780 const char* name, const char* description)
2781 : TestCaseBase(context, extParams, name, description)
2791 /** Deinitializes GLES objects created during the test. */
2792 void GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest::deinit()
2794 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2798 gl.deleteShader(m_fs_id);
2802 if (m_fs_po_id != 0)
2804 gl.deleteProgram(m_fs_po_id);
2810 gl.deleteShader(m_gs_id);
2814 if (m_gs_po_id != 0)
2816 gl.deleteProgram(m_gs_po_id);
2822 gl.deleteProgramPipelines(1, &m_ppo_id);
2828 gl.deleteVertexArrays(1, &m_vao_id);
2832 /* Release base class */
2833 TestCaseBase::deinit();
2836 /** Executes the test.
2838 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
2839 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
2840 * Note the function throws exception should an error occur!
2842 tcu::TestNode::IterateResult GeometryShaderPiplineProgramObjectWithoutActiveVSProgramTest::iterate()
2844 bool has_shader_compilation_failed = true;
2846 glw::GLenum error = GL_NO_ERROR;
2848 /* This test should only run if EXT_geometry_shader is supported. */
2849 if (!m_is_geometry_shader_extension_supported)
2851 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
2854 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2856 /* Create separable program objects. */
2857 m_fs_po_id = gl.createProgram();
2858 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2860 gl.programParameteri(m_fs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2861 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
2863 m_gs_po_id = gl.createProgram();
2864 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
2866 gl.programParameteri(m_gs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
2867 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
2869 /* Create shader objects. */
2870 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
2871 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
2873 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
2875 /* Try to link the test program object */
2876 std::string fs_code_specialized = specializeShader(1, &dummy_fs_code);
2877 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
2878 std::string gs_code_specialized = specializeShader(1, &dummy_gs_code);
2879 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
2881 if (!TestCaseBase::buildProgram(m_fs_po_id, m_fs_id, 1, /* n_sh1_body_parts */
2882 &fs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */
2883 NULL, 0, 0, /* n_sh3_body_parts */
2884 NULL, &has_shader_compilation_failed))
2886 m_testCtx.getLog() << tcu::TestLog::Message << "Fragment Shader Program object linking failed."
2887 << tcu::TestLog::EndMessage;
2893 if (!TestCaseBase::buildProgram(m_gs_po_id, m_gs_id, 1, /* n_sh1_body_parts */
2894 &gs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */
2895 NULL, 0, 0, /* n_sh3_body_parts */
2896 NULL, &has_shader_compilation_failed))
2898 m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed."
2899 << tcu::TestLog::EndMessage;
2905 /* Configure Pipeline Object. */
2906 gl.genProgramPipelines(1, &m_ppo_id);
2907 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call failed.");
2909 gl.useProgramStages(m_ppo_id, GL_FRAGMENT_SHADER_BIT, m_fs_po_id);
2910 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
2912 gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id);
2913 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
2915 /* Configure VAO. */
2916 gl.genVertexArrays(1, &m_vao_id);
2917 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
2919 gl.bindVertexArray(m_vao_id);
2920 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
2922 /* Use Program Pipeline Object. */
2923 gl.bindProgramPipeline(m_ppo_id);
2924 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call failed.");
2926 gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/);
2928 error = gl.getError();
2930 /* Check if correct error was generated. */
2931 if (GL_INVALID_OPERATION != error)
2935 m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPEARATION was generated."
2936 << tcu::TestLog::EndMessage;
2942 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2946 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2954 * @param context Test context
2955 * @param extParams Not used.
2956 * @param name Test case's name
2957 * @param description Test case's description
2959 GeometryShaderIncompatibleDrawCallModeTest::GeometryShaderIncompatibleDrawCallModeTest(Context& context,
2960 const ExtParameters& extParams,
2962 const char* description)
2963 : TestCaseBase(context, extParams, name, description)
2966 , m_number_of_gs(5 /*taken from test spec*/)
2973 /** Deinitializes GLES objects created during the test. */
2974 void GeometryShaderIncompatibleDrawCallModeTest::deinit()
2976 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2980 gl.deleteShader(m_fs_id);
2986 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
2988 gl.deleteShader(m_gs_ids[i]);
2998 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3000 gl.deleteProgram(m_po_ids[i]);
3010 gl.deleteVertexArrays(1, &m_vao_id);
3016 gl.deleteShader(m_vs_id);
3020 /* Release base class */
3021 TestCaseBase::deinit();
3024 /** Executes the test.
3026 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
3027 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
3028 * Note the function throws exception should an error occur!
3030 tcu::TestNode::IterateResult GeometryShaderIncompatibleDrawCallModeTest::iterate()
3032 /* Define 5 Geometry Shaders for purpose of this test. */
3033 const char* gs_code_points = "${VERSION}\n"
3034 "${GEOMETRY_SHADER_REQUIRE}\n"
3036 "layout (points) in;\n"
3037 "layout (points, max_vertices = 1) out;\n"
3039 "${IN_PER_VERTEX_DECL_ARRAY}"
3043 " gl_Position = gl_in[0].gl_Position;\n"
3047 const char* gs_code_lines = "${VERSION}\n"
3048 "${GEOMETRY_SHADER_REQUIRE}\n"
3050 "layout (lines) in;\n"
3051 "layout (points, max_vertices = 1) out;\n"
3053 "${IN_PER_VERTEX_DECL_ARRAY}"
3057 " gl_Position = gl_in[0].gl_Position;\n"
3061 const char* gs_code_lines_adjacency = "${VERSION}\n"
3062 "${GEOMETRY_SHADER_REQUIRE}\n"
3064 "layout (lines_adjacency) in;\n"
3065 "layout (points, max_vertices = 1) out;\n"
3067 "${IN_PER_VERTEX_DECL_ARRAY}"
3071 " gl_Position = gl_in[0].gl_Position;\n"
3075 const char* gs_code_triangles = "${VERSION}\n"
3076 "${GEOMETRY_SHADER_REQUIRE}\n"
3078 "layout (triangles) in;\n"
3079 "layout (points, max_vertices = 1) out;\n"
3081 "${IN_PER_VERTEX_DECL_ARRAY}"
3085 " gl_Position = gl_in[0].gl_Position;\n"
3089 const char* gs_code_triangles_adjacency = "${VERSION}\n"
3090 "${GEOMETRY_SHADER_REQUIRE}\n"
3092 "layout (triangles_adjacency) in;\n"
3093 "layout (points, max_vertices = 1) out;\n"
3095 "${IN_PER_VERTEX_DECL_ARRAY}"
3099 " gl_Position = gl_in[0].gl_Position;\n"
3103 bool has_shader_compilation_failed = true;
3106 m_gs_ids = new glw::GLuint[m_number_of_gs];
3107 m_po_ids = new glw::GLuint[m_number_of_gs];
3109 /* This test should only run if EXT_geometry_shader is supported. */
3110 if (!m_is_geometry_shader_extension_supported)
3112 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
3115 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3117 /* Create program objects & geometry shader objects. */
3118 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3120 m_gs_ids[i] = gl.createShader(GL_GEOMETRY_SHADER);
3121 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
3123 m_po_ids[i] = gl.createProgram();
3124 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3127 /* Create shader object. */
3128 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
3129 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
3130 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3132 /* Try to link the test program object */
3133 std::string fs_code_specialized = specializeShader(1, &dummy_fs_code);
3134 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
3136 std::string gs_codes_specialized[] = { specializeShader(1, &gs_code_points), specializeShader(1, &gs_code_lines),
3137 specializeShader(1, &gs_code_lines_adjacency),
3138 specializeShader(1, &gs_code_triangles),
3139 specializeShader(1, &gs_code_triangles_adjacency) };
3141 const char* gs_codes_specialized_raw[] = { gs_codes_specialized[0].c_str(), gs_codes_specialized[1].c_str(),
3142 gs_codes_specialized[2].c_str(), gs_codes_specialized[3].c_str(),
3143 gs_codes_specialized[4].c_str() };
3144 std::string vs_code_specialized = specializeShader(1, &dummy_vs_code);
3145 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
3147 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3149 if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */
3150 &fs_code_specialized_raw, m_gs_ids[i], 1, /* n_sh2_body_parts */
3151 &gs_codes_specialized_raw[i], m_vs_id, 1, /* n_sh3_body_parts */
3152 &vs_code_specialized_raw, &has_shader_compilation_failed))
3154 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed for i = "
3155 << "[" << i << "]." << tcu::TestLog::EndMessage;
3164 /* Configure VAO. */
3165 gl.genVertexArrays(1, &m_vao_id);
3166 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
3168 gl.bindVertexArray(m_vao_id);
3169 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
3171 for (glw::GLuint po = 0; po < m_number_of_gs; ++po)
3173 /* Use Program Object. */
3174 gl.useProgram(m_po_ids[po]);
3175 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
3179 gl.drawArrays(GL_POINTS, 0 /*starting index*/, 1 /*number of indices*/);
3181 if (GL_INVALID_OPERATION != gl.getError())
3185 m_testCtx.getLog() << tcu::TestLog::Message
3186 << "Error different than GL_INVALID_OPEARATION was generated."
3187 << tcu::TestLog::EndMessage;
3195 gl.drawArrays(GL_LINES, 0 /*starting index*/, 2 /*number of indices*/);
3197 if (GL_INVALID_OPERATION != gl.getError())
3201 m_testCtx.getLog() << tcu::TestLog::Message
3202 << "Error different than GL_INVALID_OPEARATION was generated."
3203 << tcu::TestLog::EndMessage;
3208 gl.drawArrays(GL_LINE_LOOP, 0 /*starting index*/, 2 /*number of indices*/);
3210 if (GL_INVALID_OPERATION != gl.getError())
3214 m_testCtx.getLog() << tcu::TestLog::Message
3215 << "Error different than GL_INVALID_OPEARATION was generated."
3216 << tcu::TestLog::EndMessage;
3221 gl.drawArrays(GL_LINE_STRIP, 0 /*starting index*/, 2 /*number of indices*/);
3223 if (GL_INVALID_OPERATION != gl.getError())
3227 m_testCtx.getLog() << tcu::TestLog::Message
3228 << "Error different than GL_INVALID_OPEARATION was generated."
3229 << tcu::TestLog::EndMessage;
3237 gl.drawArrays(GL_LINES_ADJACENCY_EXT, 0 /*starting index*/, 4 /*number of indices*/);
3239 if (GL_INVALID_OPERATION != gl.getError())
3243 m_testCtx.getLog() << tcu::TestLog::Message
3244 << "Error different than GL_INVALID_OPEARATION was generated."
3245 << tcu::TestLog::EndMessage;
3250 gl.drawArrays(GL_LINE_STRIP_ADJACENCY_EXT, 0 /*starting index*/, 4 /*number of indices*/);
3252 if (GL_INVALID_OPERATION != gl.getError())
3256 m_testCtx.getLog() << tcu::TestLog::Message
3257 << "Error different than GL_INVALID_OPEARATION was generated."
3258 << tcu::TestLog::EndMessage;
3266 gl.drawArrays(GL_TRIANGLES, 0 /*starting index*/, 3 /*number of indices*/);
3268 if (GL_INVALID_OPERATION != gl.getError())
3272 m_testCtx.getLog() << tcu::TestLog::Message
3273 << "Error different than GL_INVALID_OPEARATION was generated."
3274 << tcu::TestLog::EndMessage;
3279 gl.drawArrays(GL_TRIANGLE_FAN, 0 /*starting index*/, 3 /*number of indices*/);
3281 if (GL_INVALID_OPERATION != gl.getError())
3285 m_testCtx.getLog() << tcu::TestLog::Message
3286 << "Error different than GL_INVALID_OPEARATION was generated."
3287 << tcu::TestLog::EndMessage;
3292 gl.drawArrays(GL_TRIANGLE_STRIP, 0 /*starting index*/, 3 /*number of indices*/);
3294 if (GL_INVALID_OPERATION != gl.getError())
3298 m_testCtx.getLog() << tcu::TestLog::Message
3299 << "Error different than GL_INVALID_OPEARATION was generated."
3300 << tcu::TestLog::EndMessage;
3308 gl.drawArrays(GL_TRIANGLES_ADJACENCY_EXT, 0 /*starting index*/, 6 /*number of indices*/);
3310 if (GL_INVALID_OPERATION != gl.getError())
3314 m_testCtx.getLog() << tcu::TestLog::Message
3315 << "Error different than GL_INVALID_OPEARATION was generated."
3316 << tcu::TestLog::EndMessage;
3321 gl.drawArrays(GL_TRIANGLE_STRIP_ADJACENCY_EXT, 0 /*starting index*/, 6 /*number of indices*/);
3323 if (GL_INVALID_OPERATION != gl.getError())
3327 m_testCtx.getLog() << tcu::TestLog::Message
3328 << "Error different than GL_INVALID_OPEARATION was generated."
3329 << tcu::TestLog::EndMessage;
3339 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3343 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3351 * @param context Test context
3352 * @param extParams Not used.
3353 * @param name Test case's name
3354 * @param description Test case's description
3356 GeometryShaderInsufficientEmittedVerticesTest::GeometryShaderInsufficientEmittedVerticesTest(
3357 Context& context, const ExtParameters& extParams, const char* name, const char* description)
3358 : TestCaseBase(context, extParams, name, description)
3362 , m_number_of_color_components(4)
3363 , m_number_of_gs(2 /*taken from test spec*/)
3365 , m_texture_height(16)
3367 , m_texture_width(16)
3372 /* Allocate enough memory for glReadPixels() data which is respectively: width, height, RGBA components number. */
3373 m_pixels = new glw::GLubyte[m_texture_height * m_texture_width * m_number_of_color_components];
3376 /** Deinitializes GLES objects created during the test. */
3377 void GeometryShaderInsufficientEmittedVerticesTest::deinit()
3379 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3381 gl.clearColor(0.0f, 0.0f, 0.0f, 0.0f);
3383 if (m_pixels != NULL)
3391 gl.deleteFramebuffers(1, &m_fbo_id);
3397 gl.deleteShader(m_fs_id);
3403 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3405 gl.deleteShader(m_gs_ids[i]);
3415 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3417 gl.deleteProgram(m_po_ids[i]);
3425 if (m_texture_id != 0)
3427 gl.deleteTextures(1, &m_texture_id);
3433 gl.deleteVertexArrays(1, &m_vao_id);
3439 gl.deleteShader(m_vs_id);
3443 /* Release base class */
3444 TestCaseBase::deinit();
3447 /** Executes the test.
3449 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
3450 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
3451 * Note the function throws exception should an error occur!
3453 tcu::TestNode::IterateResult GeometryShaderInsufficientEmittedVerticesTest::iterate()
3455 /* Define Fragment Shader for purpose of this test. */
3456 const char* fs_code = "${VERSION}\n"
3458 "precision highp float;\n"
3460 "out vec4 result;\n"
3464 " result = vec4(1.0, 0.0, 0.0, 0.0);\n"
3467 /* Define 2 Geometry Shaders for purpose of this test. */
3468 const char* gs_line_strip = "${VERSION}\n"
3469 "${GEOMETRY_SHADER_REQUIRE}\n"
3471 "layout (points) in;\n"
3472 "layout (line_strip, max_vertices = 2) out;\n"
3474 "${IN_PER_VERTEX_DECL_ARRAY}"
3478 " gl_Position = gl_in[0].gl_Position;\n"
3479 " gl_Position.zw = vec2(0.0, 1.0);\n"
3483 const char* gs_triangle_strip = "${VERSION}\n"
3484 "${GEOMETRY_SHADER_REQUIRE}\n"
3486 "layout (points) in;\n"
3487 "layout (triangle_strip, max_vertices = 3) out;\n"
3489 "${IN_PER_VERTEX_DECL_ARRAY}"
3493 " gl_Position = gl_in[0].gl_Position;\n"
3494 " gl_Position.zw = vec2(0.0, 1.0);\n"
3497 " gl_Position = gl_in[0].gl_Position;\n"
3498 " gl_Position.zw = vec2(0.0, 1.0);\n"
3502 bool has_shader_compilation_failed = true;
3505 m_gs_ids = new glw::GLuint[m_number_of_gs];
3506 m_po_ids = new glw::GLuint[m_number_of_gs];
3508 /* This test should only run if EXT_geometry_shader is supported. */
3509 if (!m_is_geometry_shader_extension_supported)
3511 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
3514 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3516 /* Create program objects & geometry shader objects. */
3517 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3519 m_gs_ids[i] = gl.createShader(GL_GEOMETRY_SHADER);
3520 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
3522 m_po_ids[i] = gl.createProgram();
3523 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3526 /* Create shader object. */
3527 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
3528 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
3529 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3531 /* Try to link the test program object */
3532 std::string fs_code_specialized = specializeShader(1, &fs_code);
3533 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
3535 std::string gs_codes_specialized[] = { specializeShader(1, &gs_line_strip),
3536 specializeShader(1, &gs_triangle_strip) };
3538 const char* gs_codes_specialized_raw[] = { gs_codes_specialized[0].c_str(), gs_codes_specialized[1].c_str() };
3540 std::string vs_code_specialized = specializeShader(1, &dummy_vs_code);
3541 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
3543 for (glw::GLuint i = 0; i < m_number_of_gs; ++i)
3545 if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */
3546 &fs_code_specialized_raw, m_gs_ids[i], 1, /* n_sh2_body_parts */
3547 &gs_codes_specialized_raw[i], m_vs_id, 1, /* n_sh3_body_parts */
3548 &vs_code_specialized_raw, &has_shader_compilation_failed))
3550 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed for i = "
3551 << "[" << i << "]." << tcu::TestLog::EndMessage;
3560 /* Create a 2D texture. */
3561 gl.genTextures(1, &m_texture_id);
3562 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures() call failed.");
3564 gl.bindTexture(GL_TEXTURE_2D, m_texture_id);
3565 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture() call failed.");
3567 gl.texStorage2D(GL_TEXTURE_2D, 1 /*levels*/, GL_RGBA8, 16 /*width taken from spec*/,
3568 16 /*height taken from spec*/);
3569 GLU_EXPECT_NO_ERROR(gl.getError(), "glTexStorage2D() call failed.");
3571 /* Configure FBO. */
3572 gl.genFramebuffers(1, &m_fbo_id);
3573 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenFramebuffers() call failed.");
3575 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo_id);
3576 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer() call failed.");
3578 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture_id, 0 /*level*/);
3579 GLU_EXPECT_NO_ERROR(gl.getError(), "glFramebufferTexture2D() call failed.");
3581 /* Configure VAO. */
3582 gl.genVertexArrays(1, &m_vao_id);
3583 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call failed.");
3585 gl.bindVertexArray(m_vao_id);
3586 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call failed.");
3588 gl.clearColor(0.0f, 1.0f, 0.0f, 0.0f);
3589 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor() call failed.");
3591 for (glw::GLuint po = 0; po < m_number_of_gs; ++po)
3593 /* Use Program Object. */
3594 gl.useProgram(m_po_ids[po]);
3595 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
3597 gl.clear(GL_COLOR_BUFFER_BIT);
3598 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear() call failed.");
3600 gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/);
3601 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed for GL_POINTS pname.");
3603 gl.readPixels(0 /*x*/, 0 /*y*/, m_texture_width, m_texture_height, GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
3604 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels() call failed.");
3606 for (glw::GLuint pixel = 0; pixel < (m_texture_width * m_texture_height * m_number_of_color_components -
3607 m_number_of_color_components);
3608 pixel += m_number_of_color_components)
3610 if (m_pixels[pixel] != 0 && m_pixels[pixel + 1] != 255 && m_pixels[pixel + 2] != 0 &&
3611 m_pixels[pixel + 3] != 0)
3615 m_testCtx.getLog() << tcu::TestLog::Message << "Pixel [" << pixel << "] has color = ["
3616 << m_pixels[pixel] << ", " << m_pixels[pixel + 1] << ", " << m_pixels[pixel + 2]
3617 << ", " << m_pixels[pixel + 3] << "] "
3618 << "instead of [0, 255, 0, 0]." << tcu::TestLog::EndMessage;
3628 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3632 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3640 * @param context Test context
3641 * @param extParams Not used.
3642 * @param name Test case's name
3643 * @param description Test case's description
3645 GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest::
3646 GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest(Context& context,
3647 const ExtParameters& extParams,
3649 const char* description)
3650 : TestCaseBase(context, extParams, name, description)
3661 /** Deinitializes GLES objects created during the test. */
3662 void GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest::deinit()
3664 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3668 gl.deleteShader(m_gs_id);
3672 if (m_gs_po_id != 0)
3674 gl.deleteProgram(m_gs_po_id);
3680 gl.deleteProgramPipelines(1, &m_ppo_id);
3686 gl.deleteBuffers(1, &m_tfbo_id);
3692 gl.deleteVertexArrays(1, &m_vao_id);
3698 gl.deleteShader(m_vs_id);
3702 if (m_vs_po_id != 0)
3704 gl.deleteProgram(m_vs_po_id);
3708 /* Release base class */
3709 TestCaseBase::deinit();
3712 /** Executes the test.
3714 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
3715 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
3716 * Note the function throws exception should an error occur!
3718 tcu::TestNode::IterateResult GeometryShaderPipelineObjectTransformFeedbackVertexAndGeometryShaderCaptureTest::iterate()
3720 /* Define Geometry Shader for purpose of this test. */
3721 const char* gs_code =
3723 "${GEOMETRY_SHADER_REQUIRE}\n"
3724 "${IN_PER_VERTEX_DECL_ARRAY}\n"
3725 "${OUT_PER_VERTEX_DECL}\n"
3727 "layout (points) in;\n"
3728 "layout (points, max_vertices = 1) out;\n"
3730 "flat in int vertexID[];\n"
3731 "flat in ivec4 out_vs_1[];\n"
3733 "out vec4 out_gs_1;\n"
3737 " out_gs_1 = vec4(vertexID[0] * 2, vertexID[0] * 2 + 1, vertexID[0] * 2 + 2, vertexID[0] * 2 + 3);\n"
3738 " gl_Position = vec4(0, 0, 0, 1);\n"
3742 /* Define Vertex Shader for purpose of this test. */
3743 const char* vs_code = "${VERSION}\n"
3744 "${OUT_PER_VERTEX_DECL}\n"
3746 "flat out ivec4 out_vs_1;\n"
3747 "flat out int vertexID;\n"
3751 " vertexID = gl_VertexID;\n"
3752 " out_vs_1 = ivec4(gl_VertexID, gl_VertexID + 1, gl_VertexID + 2, gl_VertexID + 3);\n"
3753 " gl_Position = vec4(1.0, 0.0, 0.0, 1.0);\n"
3756 bool has_shader_compilation_failed = true;
3758 glw::GLfloat* ptrTF_data_f = NULL;
3759 glw::GLuint* ptrTF_data_ui = NULL;
3760 glw::GLfloat expected_geom_results[] = { 0.0f, 1.0f, 2.0f, 3.0f };
3761 glw::GLuint expected_vertex_results[] = { 0, 1, 2, 3 };
3762 glw::GLfloat epsilon = 1e-5f;
3764 /* This test should only run if EXT_geometry_shader is supported. */
3765 if (!m_is_geometry_shader_extension_supported)
3767 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
3770 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3772 /* Create separable program objects. */
3773 m_gs_po_id = gl.createProgram();
3774 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
3776 gl.programParameteri(m_gs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
3777 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
3779 m_vs_po_id = gl.createProgram();
3780 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
3782 gl.programParameteri(m_vs_po_id, GL_PROGRAM_SEPARABLE, GL_TRUE);
3783 GLU_EXPECT_NO_ERROR(gl.getError(), "glProgramParameteri() call failed.");
3785 /* Create shader objects. */
3786 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
3787 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
3788 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
3790 /* Try to link the test program object */
3791 std::string gs_code_specialized = specializeShader(1, &gs_code);
3792 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
3794 std::string vs_code_specialized = specializeShader(1, &vs_code);
3795 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
3797 /* Specify output variables to be captured. */
3798 const char* tf_varyings[2] = { "out_gs_1", "out_vs_1" };
3800 gl.transformFeedbackVaryings(m_gs_po_id, 1 /*count*/, &tf_varyings[0], GL_INTERLEAVED_ATTRIBS);
3801 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
3803 gl.transformFeedbackVaryings(m_vs_po_id, 1 /*count*/, &tf_varyings[1], GL_INTERLEAVED_ATTRIBS);
3804 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
3806 if (!TestCaseBase::buildProgram(m_gs_po_id, m_gs_id, 1, /* n_sh1_body_parts */
3807 &gs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */
3808 NULL, 0, 0, /* n_sh3_body_parts */
3809 NULL, &has_shader_compilation_failed))
3811 m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed."
3812 << tcu::TestLog::EndMessage;
3818 if (!TestCaseBase::buildProgram(m_vs_po_id, m_vs_id, 1, /* n_sh1_body_parts */
3819 &vs_code_specialized_raw, 0, 0, /* n_sh2_body_parts */
3820 NULL, 0, 0, /* n_sh3_body_parts */
3821 NULL, &has_shader_compilation_failed))
3823 m_testCtx.getLog() << tcu::TestLog::Message << "Geometry Shader Program object linking failed."
3824 << tcu::TestLog::EndMessage;
3830 /* Create and configure Program Pipeline Object. */
3831 gl.genProgramPipelines(1, &m_ppo_id);
3832 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenProgramPipelines() call(s) failed.");
3834 gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, m_gs_po_id);
3835 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed.");
3837 gl.useProgramStages(m_ppo_id, GL_VERTEX_SHADER_BIT, m_vs_po_id);
3838 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed.");
3840 /* Create Vertex Array Object. */
3841 gl.genVertexArrays(1, &m_vao_id);
3842 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed.");
3844 gl.bindVertexArray(m_vao_id);
3845 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed.");
3847 /* Create Buffer Object for Transform Feedback data. */
3848 gl.genBuffers(1, &m_tfbo_id);
3849 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");
3851 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
3852 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");
3854 gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLfloat) * 4, NULL, GL_STREAM_READ);
3855 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed.");
3857 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id);
3858 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed.");
3860 /* Ensure that there is no program object already bound and bind program pipeline. */
3862 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed.");
3864 gl.bindProgramPipeline(m_ppo_id);
3865 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindProgramPipeline() call(s) failed.");
3867 gl.enable(GL_RASTERIZER_DISCARD);
3868 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed.");
3870 /* First pass - Vertex and Geometry Shaders On. */
3871 gl.beginTransformFeedback(GL_POINTS);
3872 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed.");
3874 gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/);
3875 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call(s) failed.");
3877 gl.endTransformFeedback();
3878 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed.");
3880 /* Retrieve data and check if it is correct. */
3882 (glw::GLfloat*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*offset*/,
3883 sizeof(glw::GLfloat) * 4 /* four float vector components */, GL_MAP_READ_BIT);
3884 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
3886 for (size_t i = 0; i < 4; ++i)
3888 if (fabs(ptrTF_data_f[i] - expected_geom_results[i]) >= epsilon)
3895 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
3896 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
3898 ptrTF_data_f = NULL;
3905 /* Deactivate Geometry Shader Program Object from Program Pipeline Object. */
3906 gl.useProgramStages(m_ppo_id, GL_GEOMETRY_SHADER_BIT, 0 /* program */);
3907 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call(s) failed.");
3909 /* Second pass - only Vertex Shader Program On. */
3910 gl.beginTransformFeedback(GL_POINTS);
3911 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed.");
3913 gl.drawArrays(GL_POINTS, 0 /*first*/, 1 /*count*/);
3914 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call(s) failed.");
3916 gl.endTransformFeedback();
3917 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed.");
3919 gl.disable(GL_RASTERIZER_DISCARD);
3920 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed.");
3922 /* Retrieve data and check if it is correct. */
3924 (glw::GLuint*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*offset*/,
3925 sizeof(glw::GLuint) * 4 /* four float vector components */, GL_MAP_READ_BIT);
3926 GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange() call failed.");
3928 for (size_t i = 0; i < 4; ++i)
3930 if (ptrTF_data_ui[i] != expected_vertex_results[i])
3937 gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
3938 GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer() call failed.");
3940 ptrTF_data_ui = NULL;
3945 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3949 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3957 * @param context Test context
3958 * @param extParams Not used.
3959 * @param name Test case's name
3960 * @param description Test case's description
3962 GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives(
3963 Context& context, const ExtParameters& extParams, const char* name, const char* description)
3964 : TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_po_id(0), m_tfbo_id(0)
3970 /** Deinitializes GLES objects created during the test. */
3971 void GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::deinit()
3973 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
3977 gl.deleteShader(m_fs_id);
3983 gl.deleteShader(m_gs_id);
3989 gl.deleteProgram(m_po_id);
3995 gl.deleteBuffers(1, &m_tfbo_id);
4001 gl.deleteVertexArrays(1, &m_vao_id);
4007 gl.deleteShader(m_vs_id);
4011 /* Release base class */
4012 TestCaseBase::deinit();
4015 /** Executes the test.
4017 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
4018 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
4019 * Note the function throws exception should an error occur!
4021 tcu::TestNode::IterateResult GeometryShaderDrawPrimitivesDoNotMatchOutputPrimitives::iterate()
4023 /* Define Geometry Shader for purpose of this test. */
4024 const char* gs_code = "${VERSION}\n"
4025 "${GEOMETRY_SHADER_REQUIRE}\n"
4027 "layout (lines) in;\n"
4028 "layout (triangle_strip, max_vertices = 3) out;\n"
4030 "out vec4 out_gs_1;\n"
4034 " out_gs_1 = vec4(4.0, 3.0, 2.0, 1.0);\n"
4036 " gl_Position = vec4(0, 0, 0, 1);\n"
4039 " gl_Position = vec4(1, 0, 0, 1);\n"
4042 " gl_Position = vec4(1, 1, 0, 1);\n"
4048 bool has_shader_compilation_failed = true;
4050 glw::GLenum error = GL_NO_ERROR;
4052 /* This test should only run if EXT_geometry_shader is supported. */
4053 if (!m_is_geometry_shader_extension_supported)
4055 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
4058 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4060 /* Create program object. */
4061 m_po_id = gl.createProgram();
4062 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
4064 /* Specify output variables to be captured. */
4065 const char* tf_varyings[] = { "out_gs_1" };
4067 gl.transformFeedbackVaryings(m_po_id, 1 /*count*/, tf_varyings, GL_INTERLEAVED_ATTRIBS);
4068 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
4070 /* Create shader objects. */
4071 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
4072 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
4073 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
4074 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
4076 /* Try to link the test program object */
4077 std::string fs_code_specialized = specializeShader(1, &dummy_fs_code);
4078 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
4080 std::string gs_code_specialized = specializeShader(1, &gs_code);
4081 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
4083 std::string vs_code_specialized = specializeShader(1, &dummy_vs_code);
4084 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
4086 if (!TestCaseBase::buildProgram(m_po_id, m_fs_id, 1, /* n_sh1_body_parts */
4087 &fs_code_specialized_raw, m_gs_id, 1, /* n_sh2_body_parts */
4088 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh3_body_parts */
4089 &vs_code_specialized_raw, &has_shader_compilation_failed))
4091 m_testCtx.getLog() << tcu::TestLog::Message << "Program object linking failed whereas a success was expected."
4092 << tcu::TestLog::EndMessage;
4098 /* Create Vertex Array Object. */
4099 gl.genVertexArrays(1, &m_vao_id);
4100 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed.");
4102 gl.bindVertexArray(m_vao_id);
4103 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed.");
4105 /* Create Buffer Object for Transform Feedback data. */
4106 gl.genBuffers(1, &m_tfbo_id);
4107 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");
4109 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
4110 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");
4112 gl.bufferData(GL_ARRAY_BUFFER,
4113 sizeof(glw::GLfloat) * 4 * 3 /* capture 4 float vector components times 3 triangle vertices */, NULL,
4115 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed.");
4117 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id);
4118 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed.");
4120 /* Turn on program object. */
4121 gl.useProgram(m_po_id);
4122 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed.");
4124 gl.enable(GL_RASTERIZER_DISCARD);
4125 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed.");
4127 gl.beginTransformFeedback(GL_LINES);
4128 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed.");
4130 gl.drawArrays(GL_TRIANGLES, 0 /*first*/, 3 /*count*/);
4132 error = gl.getError();
4134 if (error != GL_INVALID_OPERATION)
4138 m_testCtx.getLog() << tcu::TestLog::Message << "Error different than GL_INVALID_OPEARATION was generated."
4139 << tcu::TestLog::EndMessage;
4142 gl.endTransformFeedback();
4143 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed.");
4145 gl.disable(GL_RASTERIZER_DISCARD);
4146 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed.");
4152 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4156 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4164 * @param context Test context
4165 * @param extParams Not used.
4166 * @param name Test case's name
4167 * @param description Test case's description
4169 GeometryShaderDrawCallsWhileTFPaused::GeometryShaderDrawCallsWhileTFPaused(Context& context,
4170 const ExtParameters& extParams,
4171 const char* name, const char* description)
4172 : TestCaseBase(context, extParams, name, description), m_fs_id(0), m_gs_id(0), m_tfbo_id(0)
4178 /** Deinitializes GLES objects created during the test. */
4179 void GeometryShaderDrawCallsWhileTFPaused::deinit()
4181 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4185 gl.deleteShader(m_fs_id);
4191 gl.deleteShader(m_gs_id);
4195 for (int i = 0; i < 15 /* All combinations of possible inputs and outputs in GS */; ++i)
4197 if (m_po_ids[i] != 0)
4199 gl.deleteProgram(m_po_ids[i]);
4206 gl.deleteBuffers(1, &m_tfbo_id);
4212 gl.deleteVertexArrays(1, &m_vao_id);
4218 gl.deleteShader(m_vs_id);
4222 /* Release base class */
4223 TestCaseBase::deinit();
4226 /** Executes the test.
4228 * Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
4229 * @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
4230 * Note the function throws exception should an error occur!
4232 tcu::TestNode::IterateResult GeometryShaderDrawCallsWhileTFPaused::iterate()
4234 /* Define 15 (all combinations of possible inputs and outputs in geometry shader) Geometry Shaders for purpose of this test. */
4235 const std::string gs_inputs[] = { "points", "lines", "lines_adjacency", "triangles", "triangles_adjacency" };
4236 const std::string gs_outputs[] = { "points", "line_strip", "triangle_strip" };
4237 const std::string gs_max_output_vertices[] = { "1", "2", "3" };
4239 const unsigned short number_of_combinations =
4240 (sizeof(gs_inputs) / sizeof(gs_inputs[0]) * (sizeof(gs_outputs) / sizeof(gs_outputs[0])));
4242 std::string gs_codes[number_of_combinations];
4243 glw::GLenum errorCode;
4245 for (size_t i = 0; i < (sizeof(gs_inputs) / sizeof(gs_inputs[0])) /*5 possible GS inputs*/; ++i)
4247 for (size_t j = 0; j < (sizeof(gs_outputs) / sizeof(gs_outputs[0])) /*3 possible GS outputs*/; ++j)
4249 /* This shader will not emit primitives for anything but points.
4250 * We do so, because we just need to make sure that, while transform feedback
4251 * is paused, all draw calls executed with an active program object which
4252 * includes a geometry shader, are valid.
4254 gs_codes[j + 3 * i] = "${VERSION}\n"
4255 "${GEOMETRY_SHADER_REQUIRE}\n"
4258 gs_inputs[i] + ") in;\n"
4260 gs_outputs[j] + ", max_vertices = " + gs_max_output_vertices[j] +
4263 "out vec2 out_gs_1;\n"
4267 " out_gs_1 = vec2(1.0, 2.0);\n"
4268 " gl_Position = vec4(0, 0, 0, 1);\n"
4274 bool has_shader_compilation_failed = true;
4276 const glw::GLuint tf_modes[3] = { GL_POINTS, GL_LINES, GL_TRIANGLES };
4277 const glw::GLuint draw_call_modes[5] = { GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES,
4278 GL_TRIANGLES_ADJACENCY };
4280 /* This test should only run if EXT_geometry_shader is supported. */
4281 if (!m_is_geometry_shader_extension_supported)
4283 throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
4286 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
4288 /* Create program objects. */
4289 for (int i = 0; i < number_of_combinations; ++i)
4291 m_po_ids[i] = gl.createProgram();
4293 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call(s) failed.");
4295 /* Specify output variables to be captured. */
4296 const char* tf_varyings[] = { "out_gs_1" };
4298 for (int i = 0; i < number_of_combinations; ++i)
4300 gl.transformFeedbackVaryings(m_po_ids[i], 1 /*count*/, tf_varyings, GL_INTERLEAVED_ATTRIBS);
4302 GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings() call(s) failed.");
4304 /* Create shader objects. */
4305 m_fs_id = gl.createShader(GL_FRAGMENT_SHADER);
4306 m_gs_id = gl.createShader(GL_GEOMETRY_SHADER);
4307 m_vs_id = gl.createShader(GL_VERTEX_SHADER);
4308 GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call(s) failed.");
4310 /* Try to link the test program object */
4311 std::string fs_code_specialized = specializeShader(1, &dummy_fs_code);
4312 const char* fs_code_specialized_raw = fs_code_specialized.c_str();
4314 std::string vs_code_specialized = specializeShader(1, &dummy_vs_code);
4315 const char* vs_code_specialized_raw = vs_code_specialized.c_str();
4317 for (int i = 0; i < number_of_combinations; ++i)
4319 const char* gs_code = gs_codes[i].c_str();
4320 std::string gs_code_specialized = specializeShader(1, &gs_code);
4321 const char* gs_code_specialized_raw = gs_code_specialized.c_str();
4323 if (!TestCaseBase::buildProgram(m_po_ids[i], m_fs_id, 1, /* n_sh1_body_parts */
4324 &fs_code_specialized_raw, m_gs_id, 1, /* n_sh2_body_parts */
4325 &gs_code_specialized_raw, m_vs_id, 1, /* n_sh3_body_parts */
4326 &vs_code_specialized_raw, &has_shader_compilation_failed))
4328 m_testCtx.getLog() << tcu::TestLog::Message
4329 << "Program object linking failed whereas a success was expected."
4330 << tcu::TestLog::EndMessage;
4341 /* Create Vertex Array Object. */
4342 gl.genVertexArrays(1, &m_vao_id);
4343 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays() call(s) failed.");
4345 gl.bindVertexArray(m_vao_id);
4346 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray() call(s) failed.");
4348 /* Create Buffer Object for Transform Feedback data. */
4349 gl.genBuffers(1, &m_tfbo_id);
4350 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers() call(s) failed.");
4352 gl.bindBuffer(GL_ARRAY_BUFFER, m_tfbo_id);
4353 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer() call(s) failed.");
4355 gl.bufferData(GL_ARRAY_BUFFER,
4356 sizeof(glw::GLfloat) * 2 * 3 /* capture 2 float vector components times 3 triangle vertices */, NULL,
4358 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData() call(s) failed.");
4360 gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0 /*binding index*/, m_tfbo_id);
4361 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase() call(s) failed.");
4363 gl.enable(GL_RASTERIZER_DISCARD);
4364 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable() call(s) failed.");
4366 for (int i = 0; i < 3 /* number of TF modes */ && result; ++i)
4368 for (int j = 0; j < 5 /*number of draw call modes*/ && result; ++j)
4370 for (int k = 0; k < 3 /* number of output GS primitive types */; ++k)
4372 /* Turn on program object. */
4373 gl.useProgram(m_po_ids[k + 3 * j]);
4374 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call(s) failed.");
4376 gl.beginTransformFeedback(tf_modes[i]);
4377 GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback() call(s) failed.");
4379 gl.pauseTransformFeedback();
4380 GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback() call(s) failed.");
4382 gl.drawArrays(draw_call_modes[j], 0 /*first*/, 3 /*count*/);
4383 errorCode = gl.getError();
4385 gl.resumeTransformFeedback();
4386 GLU_EXPECT_NO_ERROR(gl.getError(), "glResumeTransformFeedback() call(s) failed.");
4388 gl.endTransformFeedback();
4389 GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback() call(s) failed.");
4391 /* If draw call fails stop test execution. */
4392 if (GL_NO_ERROR != errorCode)
4394 m_testCtx.getLog() << tcu::TestLog::Message
4395 << "glDrawArrays() call generated an error while transform feedback was paused."
4396 << tcu::TestLog::EndMessage;
4405 gl.disable(GL_RASTERIZER_DISCARD);
4406 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable() call(s) failed.");
4412 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
4416 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
4422 } // namespace glcts