#ifndef _ESEXTCTESSELLATIONSHADERTCTE_HPP #define _ESEXTCTESSELLATIONSHADERTCTE_HPP /*------------------------------------------------------------------------- * OpenGL Conformance Test Suite * ----------------------------- * * Copyright (c) 2014-2016 The Khronos Group Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /*! * \file * \brief */ /*-------------------------------------------------------------------*/ #include "../esextcTestCaseBase.hpp" #include "esextcTessellationShaderUtils.hpp" #include "gluShaderUtil.hpp" #include "tcuDefs.hpp" namespace glcts { /** A DEQP CTS test group that collects all tests that verify various * interactions between tessellation control and tessellation evaluation * shaders */ class TessellationShaderTCTETests : public glcts::TestCaseGroupBase { public: /* Public methods */ TessellationShaderTCTETests(glcts::Context& context, const ExtParameters& extParams); virtual ~TessellationShaderTCTETests(void) { } void init(void); private: /* Private methods */ TessellationShaderTCTETests(const TessellationShaderTCTETests& other); TessellationShaderTCTETests& operator=(const TessellationShaderTCTETests& other); }; /** Implementation of Test Case 50 * * Make sure that tessellation control shader can correctly read per-vertex * values, as modified by a vertex shader. Verify per-vertex gl_Position * and gl_PointSize values are assigned values as in vertex shader. * Make sure that per-vertex & per-patch outputs written to in tessellation * control shader can be correctly read by tessellation evaluation shader. * Pay special attention to gl_Position and gl_PointSize. * Make sure that per-vertex output variables of a tessellation evaluation * shader can be correctly read by a geometry shader. * * Note: gl_PointSize should only be passed down the rendering pipeline and * then verified by the test if GL_EXT_tessellation_point_size * extension support is reported. * * 1. The test should run in three iterations: * 1a. Vertex + TC + TE stages should be defined; * 1b. Vertex + TC + TE + GS stages should be defined (if geometry * shaders are supported); * 2. The test should be run for all three tessellator primitive types, * with inner and outer tessellation levels set to reasonably small * values but not equal to 1 for the levels that affect the tessellation * process for the primitive type considered. * 3. Vertex shader should set: * 3a. gl_Position to vec4(gl_VertexID); * 3b. gl_PointSize to 1.0 / float(gl_VertexID); * 3c. an output vec4 variable to: * vec4(gl_VertexID, gl_VertexID * 0.5, gl_VertexID * 0.25, gl_VertexID * 0.125); * 3d. an outpt ivec4 variable to: * ivec4(gl_VertexID, gl_VertexID + 1, gl_VertexID + 2, gl_VertexID + 3); * 4. TC shader should define corresponding input variables and patch * their contents through (for gl_InvocationID invocation) to * differently named output variables; * gl_Position and gl_PointSize values for the invocation * considered should also be forwarded. * One of the invocations for each patch should also set a vec4 * and ivec4 per-patch variables to values as above, multiplied by two. * 5. TE shader should define corresponding input variables and patch * their contents through to a differently named output variables; * gl_Position, gl_PointSize, gl_TessLevelOuter and gl_TessLevelInner * values for the primitive being processed should also be forwarded. * If TC is present in the pipeline, TE stage should also define * two new output variables and set them to per-patch variable * values, as set by TC. * 6. Geometry shader should define corresponding input variables and * patch their contents through to a differently named output * variables; * 7. Test implementation should retrieve the captured data once a single * instance of geometry is rendered and verify it. * **/ class TessellationShaderTCTEDataPassThrough : public TestCaseBase { public: /* Public methods */ TessellationShaderTCTEDataPassThrough(Context& context, const ExtParameters& extParams); virtual ~TessellationShaderTCTEDataPassThrough(void) { } virtual void deinit(); void initTest(void); virtual IterateResult iterate(void); private: /* Private type definitions */ /* Stores all properties of a single test run */ typedef struct _run { glw::GLuint fs_id; glw::GLuint gs_id; glw::GLuint po_id; glw::GLuint tcs_id; glw::GLuint tes_id; glw::GLuint vs_id; _tessellation_primitive_mode primitive_mode; unsigned int n_result_vertices_per_patch; std::vector result_tc_pointSize_data; std::vector<_vec4> result_tc_position_data; std::vector<_vec4> result_tc_value1_data; std::vector<_ivec4> result_tc_value2_data; std::vector<_vec4> result_te_patch_data; std::vector result_te_pointSize_data; std::vector<_vec4> result_te_position_data; /* Constructor */ _run() { fs_id = 0; gs_id = 0; n_result_vertices_per_patch = 0; po_id = 0; primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; tcs_id = 0; tes_id = 0; vs_id = 0; } } _run; /* Encapsulates all test runs */ typedef std::vector<_run> _runs; typedef _runs::const_iterator _runs_const_iterator; /* Private methods */ void deinitTestRun(_run& run); void executeTestRun(_run& run, _tessellation_primitive_mode primitive_mode, bool should_use_geometry_shader, bool should_pass_point_size_data_in_gs, bool should_pass_point_size_data_in_ts); /* Private variables */ glw::GLuint m_bo_id; const unsigned int m_n_input_vertices_per_run; _runs m_runs; TessellationShaderUtils* m_utils_ptr; glw::GLuint m_vao_id; }; /** Implementation of Test Case 52 * * This test should iterate over all vertex ordering / spacing / primitive / * point mode permutations, as well as over a number of inner/outer tessellation * level configurations. * The tessellation evaluation shaders used for the test should: * * - Make sure that up to gl_MaxPatchVertices vertices' data can be read in * a tessellation evaluation shader. * - Make sure gl_Position and gl_PointSize per-vertex variables can be * accessed for all vertices. * * The tessellation control shader used for the test should set iteration- * -specific properties and configure aforementioned per-vertex variables * accordingly. * * Both pipeline objects and program objects should be used for the purpose * of the test. For each case, the test should verify that correct objects * defining tessellation control and tessellation stages are reported. * For program objects' case, the test should also confirm that valid shader * types are reported for TC and TE shader objects. * The test should also verify that no objects are assigned to either * stage by default. * * The test should check that tessellation-specific properties are reported * correctly. * **/ class TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize : public TestCaseBase { public: /* Public methods */ TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize(Context& context, const ExtParameters& extParams); virtual ~TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize(void) { } virtual void deinit(); void initTest(void); virtual IterateResult iterate(void); private: /* Private type definitions */ /** Describes a single test run */ typedef struct _run { glw::GLuint fs_id; glw::GLuint fs_program_id; glw::GLuint pipeline_object_id; glw::GLuint po_id; glw::GLuint tc_id; glw::GLuint tc_program_id; glw::GLuint te_id; glw::GLuint te_program_id; glw::GLuint vs_id; glw::GLuint vs_program_id; glw::GLfloat inner[2]; glw::GLfloat outer[4]; bool point_mode; _tessellation_primitive_mode primitive_mode; _tessellation_shader_vertex_ordering vertex_ordering; _tessellation_shader_vertex_spacing vertex_spacing; std::vector result_pointsize_data; std::vector<_vec4> result_position_data; std::vector<_vec2> result_value1_data; std::vector<_ivec4> result_value2_data; /* Constructor */ _run() : fs_id(0) , fs_program_id(0) , pipeline_object_id(0) , po_id(0) , tc_id(0) , tc_program_id(0) , te_id(0) , te_program_id(0) , vs_id(0) , vs_program_id(0) , point_mode(false) , primitive_mode(TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN) , vertex_ordering(TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN) , vertex_spacing(TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN) { memset(inner, 0, sizeof(inner)); memset(outer, 0, sizeof(outer)); } } _run; /** Describes a set of test runs */ typedef std::vector<_run> _runs; typedef _runs::const_iterator _runs_const_iterator; /* Private methods */ void deinitTestRun(_run& run); std::string getFragmentShaderCode(bool should_accept_pointsize_data); std::string getTessellationControlShaderCode(bool should_pass_pointsize_data, const glw::GLfloat* inner_tess_levels, const glw::GLfloat* outer_tess_levels); std::string getTessellationEvaluationShaderCode(bool should_pass_pointsize_data, _tessellation_primitive_mode primitive_mode, _tessellation_shader_vertex_ordering vertex_ordering, _tessellation_shader_vertex_spacing vertex_spacing, bool is_point_mode_enabled); std::string getVertexShaderCode(bool should_pass_pointsize_data); void initTestRun(_run& run); /* Private variables */ glw::GLuint m_bo_id; glw::GLint m_gl_max_patch_vertices_value; glw::GLint m_gl_max_tess_gen_level_value; _runs m_runs; TessellationShaderUtils* m_utils_ptr; glw::GLuint m_vao_id; }; /** Implementation of Test Case 36 * * Make sure that values of gl_in[] in a tessellation evaluation shader are * taken from output variables of a tessellation control shader if one is * present. This test should verify that the values are not taken from * a vertex shader. * * Technical details: * * 0. A program consisting of vertex, TC and TE stages should be considered. * 1. Vertex shader should output a set of output variables of different types. * 2. TC shader should define exactly the same set of output variables. * The data the shader writes to these variables must be different than * in the vertex shader's case. * 3. TE shader should define these variables as input variables. It should * copy their values to a set of corresponding output variables, which * the test should then validate by means of Transform Feedback. * **/ class TessellationShaderTCTEgl_in : public TestCaseBase { public: /* Public methods */ TessellationShaderTCTEgl_in(Context& context, const ExtParameters& extParams); virtual ~TessellationShaderTCTEgl_in(void) { } virtual void deinit(); void initTest(void); virtual IterateResult iterate(void); private: /* Private methods */ void getXFBProperties(const glw::GLchar*** out_names, glw::GLint* out_n_names, glw::GLint* out_xfb_size); /* Private variables */ glw::GLuint m_bo_id; glw::GLuint m_fs_id; glw::GLuint m_po_id; glw::GLuint m_tcs_id; glw::GLuint m_tes_id; glw::GLuint m_vao_id; glw::GLuint m_vs_id; }; /** Implementation of Test Case 37 * * Make sure that gl_TessLevelOuter[] and gl_TessLevelInner[] accessed from * tessellation evaluation shader hold values, as used in tessellation control * shader for a processed patch (assuming tessellation control shader is * present in the pipeline) * Make sure that gl_TessLevelOuter[] and gl_TessLevelInner[] accessed from * tessellation evaluation shader hold patch parameter values, if no * tessellation control shader is present in the pipeline. * Reported values should not be clamped and rounded, owing to active * vertex spacing mode. * * Technical details: * * 0. The test should use two program objects: one defining a TC stage, * the other one should lack a tessellation control shader. * 1. For the first case, the test implementation should check a couple * of different inner/outer tessellation level configurations by reading * them from an uniform that the test will update prior to doing a draw * call. * For the other case, the parameters can be modified using ES API. * 2. TE should output inner and output tessellation levels to a varying, * for which Transform Feedback should be configured. * 3. Test passes if tessellation levels in TE stage match the ones * defined in TC stage. Pay attention to making sure no clamping * or rounding occurs for any vertex spacing mode. * **/ class TessellationShaderTCTEgl_TessLevel : public TestCaseBase { public: /* Public methods */ TessellationShaderTCTEgl_TessLevel(Context& context, const ExtParameters& extParams); virtual ~TessellationShaderTCTEgl_TessLevel(void) { } virtual void deinit(); void initTest(void); virtual IterateResult iterate(void); private: /* Private type definitions */ typedef struct _test_descriptor { _tessellation_test_type type; _tessellation_shader_vertex_spacing vertex_spacing; glw::GLuint fs_id; glw::GLuint po_id; glw::GLuint tcs_id; glw::GLuint tes_id; glw::GLuint vs_id; glw::GLint inner_tess_levels_uniform_location; glw::GLint outer_tess_levels_uniform_location; _test_descriptor() { fs_id = 0; po_id = 0; tcs_id = 0; tes_id = 0; vs_id = 0; inner_tess_levels_uniform_location = 0; outer_tess_levels_uniform_location = 0; type = TESSELLATION_TEST_TYPE_COUNT; vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; } } _test_descriptor; typedef std::vector<_test_descriptor> _tests; typedef _tests::const_iterator _tests_const_iterator; /* Private methods */ void deinitTestDescriptor(_test_descriptor* test_ptr); void initTestDescriptor(_tessellation_test_type test_type, _test_descriptor* out_test_ptr, _tessellation_shader_vertex_spacing vertex_spacing_mode); /* Private variables */ glw::GLint m_gl_max_tess_gen_level_value; glw::GLuint m_bo_id; _tests m_tests; glw::GLuint m_vao_id; }; /** Implementation of Test Case 35 * * Make sure that the number of vertices in input patch of a tessellation * evaluation shader is: * * * fixed and equal to tessellation control shader output patch size parameter * from the time the program object was linked last time, should tessellation * control shader be present in the pipeline; * * equal to patch size parameter at the time of a draw call, if there * is no tessellation control shader present in the pipeline. * * Technical details: * * 0. Apart from the two cases described in the test summary, the implementation * should also iterate over a number of different patch size values. * 1. TE shader should save gl_PatchVerticesIn.length() in an output * variable. This variable should be XFBed to a buffer object and then * verified in the actual test. * **/ class TessellationShaderTCTEgl_PatchVerticesIn : public TestCaseBase { public: /* Public methods */ TessellationShaderTCTEgl_PatchVerticesIn(Context& context, const ExtParameters& extParams); virtual ~TessellationShaderTCTEgl_PatchVerticesIn(void) { } virtual void deinit(); void initTest(void); virtual IterateResult iterate(void); private: /* Private type definitions */ typedef struct _test_descriptor { _tessellation_test_type type; glw::GLuint fs_id; glw::GLuint po_id; glw::GLuint tcs_id; glw::GLuint tes_id; glw::GLuint vs_id; unsigned int input_patch_size; _test_descriptor() { fs_id = 0; po_id = 0; tcs_id = 0; tes_id = 0; vs_id = 0; input_patch_size = 0; type = TESSELLATION_TEST_TYPE_COUNT; } } _test_descriptor; typedef std::vector<_test_descriptor> _tests; typedef _tests::const_iterator _tests_const_iterator; /* Private methods */ void deinitTestDescriptor(_test_descriptor* test_ptr); void initTestDescriptor(_tessellation_test_type test_type, _test_descriptor* out_test_ptr, unsigned int input_patch_size); /* Private variables */ glw::GLint m_gl_max_patch_vertices_value; glw::GLuint m_bo_id; _tests m_tests; glw::GLuint m_vao_id; }; } // namespace glcts #endif // _ESEXTCTESSELLATIONSHADERTCTE_HPP