| #ifndef _ESEXTCTESSELLATIONSHADERINVARIANCE_HPP |
| #define _ESEXTCTESSELLATIONSHADERINVARIANCE_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 "glwEnums.hpp" |
| #include "tcuDefs.hpp" |
| |
| namespace glcts |
| { |
| |
| /** A DEQP CTS test group that collects all tests that verify invariance |
| * conformance. |
| */ |
| class TessellationShaderInvarianceTests : public glcts::TestCaseGroupBase |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceTests(glcts::Context& context, const ExtParameters& extParams); |
| |
| virtual ~TessellationShaderInvarianceTests(void) |
| { |
| } |
| |
| virtual void init(void); |
| |
| private: |
| /* Private methods */ |
| TessellationShaderInvarianceTests(const TessellationShaderInvarianceTests& other); |
| TessellationShaderInvarianceTests& operator=(const TessellationShaderInvarianceTests& other); |
| }; |
| |
| /** Base class that provides shared invariance test implementation. Invariance |
| * rule test need only to implement the abstract methods. |
| **/ |
| class TessellationShaderInvarianceBaseTest : public TestCaseBase |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceBaseTest(Context& context, const ExtParameters& extParams, const char* name, |
| const char* description); |
| |
| virtual ~TessellationShaderInvarianceBaseTest(void) |
| { |
| } |
| |
| virtual void deinit(void); |
| virtual IterateResult iterate(void); |
| |
| protected: |
| /* Protected variables */ |
| TessellationShaderUtils* m_utils_ptr; |
| |
| virtual void executeDrawCall(unsigned int n_iteration); |
| virtual unsigned int getAmountOfIterations() = 0; |
| virtual unsigned int getDrawCallCountArgument(); |
| virtual std::string getFSCode(unsigned int n_iteration); |
| virtual const char* getInnerTessLevelUniformName(); |
| virtual const char* getOuterTessLevelUniformName(); |
| |
| virtual void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, |
| float* out_outer_tess_levels, bool* out_point_mode, |
| _tessellation_primitive_mode* out_primitive_mode, |
| _tessellation_shader_vertex_ordering* out_vertex_ordering, |
| unsigned int* out_result_buffer_size) = 0; |
| |
| virtual std::string getTCCode(unsigned int n_iteration); |
| virtual std::string getTECode(unsigned int n_iteration) = 0; |
| virtual std::string getVSCode(unsigned int n_iteration); |
| |
| virtual void getXFBProperties(unsigned int n_iteration, unsigned int* out_n_names, const char*** out_names); |
| |
| virtual void verifyResultDataForIteration(unsigned int n_iteration, const void* data); |
| |
| virtual void verifyResultData(const void** all_iterations_data); |
| |
| private: |
| /* Private type definitions */ |
| |
| /* Private methods */ |
| void initTest(); |
| |
| /* Private variables */ |
| typedef struct _test_program |
| { |
| glw::GLuint po_id; |
| |
| glw::GLuint inner_tess_level_uniform_location; |
| glw::GLuint outer_tess_level_uniform_location; |
| |
| } _test_program; |
| |
| /* Defines a vector of program objects. Index corresponds to iteration index */ |
| typedef std::vector<_test_program> _programs; |
| typedef _programs::const_iterator _programs_const_iterator; |
| typedef _programs::iterator _programs_iterator; |
| |
| glw::GLuint m_bo_id; |
| _programs m_programs; |
| glw::GLuint m_qo_tfpw_id; |
| glw::GLuint m_vao_id; |
| }; |
| |
| /** Implementation of Test Case 42 |
| * |
| * Make sure that invariance rule 1 is adhered to. Using a program object |
| * consisting of a fragment/tessellation control/tessellation evaluation/ |
| * vertex shaders, render three points/lines/triangles (A, B, C) and |
| * store vertices output by the tessellation evaluation shader. Then render |
| * the geometry in (B, C, A) order, using the same program object. Test |
| * passes if vertices stored in two different iterations for the same |
| * triangle are identical. Owing to rule 8, assume zero epsilon. |
| **/ |
| class TessellationShaderInvarianceRule1Test : public TessellationShaderInvarianceBaseTest |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceRule1Test(Context& context, const ExtParameters& extParams); |
| virtual ~TessellationShaderInvarianceRule1Test(); |
| |
| protected: |
| /* Protected methods */ |
| unsigned int getAmountOfIterations(); |
| unsigned int getDrawCallCountArgument(); |
| |
| void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, |
| bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, |
| _tessellation_shader_vertex_ordering* out_vertex_ordering, |
| unsigned int* out_result_buffer_size); |
| |
| std::string getTECode(unsigned int n_iteration); |
| void verifyResultData(const void** all_iterations_data); |
| }; |
| |
| /** Implementation of Test Case 43 |
| * |
| * Make sure that invariance rule 2 is adhered to. Using a program object |
| * consisting of a fragment/tessellation control/tessellation evaluation/ |
| * vertex shaders, render a number of full-screen triangles/quads, each |
| * instance rendered with different inner tessellation level but identical |
| * outer tessellation level and spacing input layout qualifiers. Test passes |
| * if outer edge's vertices are the same for both types of geometry |
| * (each type considered separately). |
| **/ |
| class TessellationShaderInvarianceRule2Test : public TessellationShaderInvarianceBaseTest |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceRule2Test(Context& context, const ExtParameters& extParams); |
| virtual ~TessellationShaderInvarianceRule2Test(); |
| |
| protected: |
| /* Protected methods */ |
| unsigned int getAmountOfIterations(); |
| |
| void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, |
| bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, |
| _tessellation_shader_vertex_ordering* out_vertex_ordering, |
| unsigned int* out_result_buffer_size); |
| |
| std::string getTECode(unsigned int n_iteration); |
| void verifyResultData(const void** all_iterations_data); |
| |
| private: |
| /* Private variables */ |
| unsigned int m_n_tessellated_vertices[4 /* iterations in total */]; |
| }; |
| |
| /** Implementation of Test Case 44 |
| * |
| * Make sure that invariance rule 3 is adhered to. Using a program object |
| * consisting of a fragment/tessellation control/tessellation evaluation/ |
| * vertex shaders, tessellate a number of triangles/quads/isolines geometry |
| * with different inner/outer/vertex spacing input layout qualifiers. |
| * Capture vertices generated by tessellation evaluation stage and make sure |
| * that generated vertices are symmetrical. Owing to rule 8, assume zero |
| * epsilon. |
| **/ |
| class TessellationShaderInvarianceRule3Test : public TessellationShaderInvarianceBaseTest |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceRule3Test(Context& context, const ExtParameters& extParams); |
| virtual ~TessellationShaderInvarianceRule3Test(); |
| |
| protected: |
| /* Protected methods */ |
| unsigned int getAmountOfIterations(); |
| |
| void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, |
| bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, |
| _tessellation_shader_vertex_ordering* out_vertex_ordering, |
| unsigned int* out_result_buffer_size); |
| |
| std::string getTECode(unsigned int n_iteration); |
| |
| void verifyResultDataForIteration(unsigned int n_iteration, const void* data); |
| |
| private: |
| /* Private type definitions */ |
| typedef struct _test_iteration |
| { |
| glw::GLfloat inner_tess_levels[2]; |
| glw::GLfloat outer_tess_levels[4]; |
| _tessellation_primitive_mode primitive_mode; |
| _tessellation_shader_vertex_spacing vertex_spacing; |
| |
| unsigned int n_vertices; |
| |
| _test_iteration() |
| { |
| memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); |
| memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); |
| |
| primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; |
| vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; |
| |
| n_vertices = 0; |
| } |
| } _test_iteration; |
| |
| typedef std::vector<_test_iteration> _test_iterations; |
| typedef _test_iterations::const_iterator _test_iterations_const_iterator; |
| |
| /* Private methods */ |
| void deinitTestIterations(); |
| void initTestIterations(); |
| |
| /* Private fields */ |
| _test_iterations m_test_iterations; |
| }; |
| |
| /** Implementation of Test Case 45 |
| * |
| * Make sure that invariance rule 4 is adhered to. Using a program object |
| * consisting of a fragment/tessellation control/tessellation evaluation/ |
| * vertex shaders, tessellate a number of triangular and quad geometry with |
| * different inner tessellation level input layout qualifiers. |
| * Capture vertices generated by tessellation evaluation stage and make sure |
| * that all sets of vertices generated when subdividing outer edges are |
| * independent of the specific edge subdivided. |
| * |
| * Technical details: |
| * |
| * 1. The test should use a number of different inner+outer |
| * tessellation levels+vertex spacing mode configuration |
| * combinations, each resulting in a different vertex set for |
| * the generator primitive type considered. |
| * In first iteration, it should draw a screen quad, and |
| * in the other a triangle should be rendered. |
| * 2. The test should capture vertices output in TE stage. The |
| * rasterizer discard mode can be enabled, as the test is not |
| * expected to analyse visual output. |
| * 3. For quad tessellation, the test should identify vertices |
| * generated for top outer edge and make sure that remaining |
| * outer edges of the quad are built of vertices that conform |
| * to the rule. |
| * 4. For triangular tessellation, the test should identify vertices |
| * generated for one of the outer edges and then check if the other |
| * two outer edges have been generated in conformance to the rule. |
| **/ |
| class TessellationShaderInvarianceRule4Test : public TessellationShaderInvarianceBaseTest |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceRule4Test(Context& context, const ExtParameters& extParams); |
| virtual ~TessellationShaderInvarianceRule4Test(); |
| |
| protected: |
| /* Protected methods */ |
| unsigned int getAmountOfIterations(); |
| |
| void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, |
| bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, |
| _tessellation_shader_vertex_ordering* out_vertex_ordering, |
| unsigned int* out_result_buffer_size); |
| |
| std::string getTECode(unsigned int n_iteration); |
| |
| void verifyResultDataForIteration(unsigned int n_iteration, const void* data); |
| |
| private: |
| /* Private type definitions */ |
| typedef struct _test_iteration |
| { |
| glw::GLfloat inner_tess_levels[2]; |
| glw::GLfloat outer_tess_levels[4]; |
| _tessellation_primitive_mode primitive_mode; |
| _tessellation_shader_vertex_spacing vertex_spacing; |
| |
| unsigned int n_vertices; |
| |
| _test_iteration() |
| { |
| memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); |
| memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); |
| |
| primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; |
| vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; |
| |
| n_vertices = 0; |
| } |
| } _test_iteration; |
| |
| typedef std::vector<_test_iteration> _test_iterations; |
| typedef _test_iterations::const_iterator _test_iterations_const_iterator; |
| |
| /* Private methods */ |
| void deinitTestIterations(); |
| void initTestIterations(); |
| |
| bool isVertexDefined(const float* vertex_data, unsigned int n_vertices, const float* vertex_data_seeked, |
| unsigned int n_vertex_data_seeked_components); |
| |
| /* Private fields */ |
| _test_iterations m_test_iterations; |
| }; |
| |
| /** Implementation of Test Case 46 |
| * |
| * Make sure that Rule 5 is adhered to. Using a program object |
| * consisting of a fragment/tessellation control/tessellation evaluation/ |
| * vertex shaders, tessellate a number of triangles/quads/isolines |
| * geometry with different vertex ordering input layout qualifiers. Capture |
| * vertices generated by tessellation evaluation stage and make sure that each |
| * iteration defines exactly the same set of vertices, although in different |
| * order. |
| * |
| **/ |
| class TessellationShaderInvarianceRule5Test : public TessellationShaderInvarianceBaseTest |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceRule5Test(Context& context, const ExtParameters& extParams); |
| virtual ~TessellationShaderInvarianceRule5Test(); |
| |
| protected: |
| /* Protected methods */ |
| unsigned int getAmountOfIterations(); |
| |
| void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, |
| bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, |
| _tessellation_shader_vertex_ordering* out_vertex_ordering, |
| unsigned int* out_result_buffer_size); |
| |
| std::string getTECode(unsigned int n_iteration); |
| void verifyResultData(const void** all_iterations_data); |
| |
| private: |
| /* Private type definitions */ |
| typedef struct _test_iteration |
| { |
| glw::GLfloat inner_tess_levels[2]; |
| glw::GLfloat outer_tess_levels[4]; |
| _tessellation_primitive_mode primitive_mode; |
| _tessellation_shader_vertex_ordering vertex_ordering; |
| |
| unsigned int n_vertices; |
| |
| _test_iteration() |
| { |
| memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); |
| memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); |
| |
| primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; |
| vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN; |
| |
| n_vertices = 0; |
| } |
| } _test_iteration; |
| |
| typedef std::vector<_test_iteration> _test_iterations; |
| typedef _test_iterations::const_iterator _test_iterations_const_iterator; |
| |
| /* Private methods */ |
| void deinitTestIterations(); |
| _test_iteration& getTestForIteration(unsigned int n_iteration); |
| void initTestIterations(); |
| bool isVertexDefined(const float* vertex_data, unsigned int n_vertices, const float* vertex_data_seeked, |
| unsigned int n_vertex_data_seeked_components); |
| |
| /* Private fields */ |
| _test_iterations m_test_triangles_iterations; |
| _test_iterations m_test_quads_iterations; |
| }; |
| |
| /** Implementation of Test Case 47 |
| * |
| * Make sure that invariance rule 6 is adhered to. Using a program object |
| * consisting of a fragment/tessellation control/tessellation evaluation/ |
| * vertex shaders, tessellate a number of triangles/quads geometry |
| * with different inner tessellation levels/vertex spacing input layout qualifiers. |
| * Capture vertices generated by tessellation evaluation stage and make sure |
| * that all interior triangles generated during tessellation are identical |
| * except for vertex and triangle order. |
| **/ |
| class TessellationShaderInvarianceRule6Test : public TessellationShaderInvarianceBaseTest |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceRule6Test(Context& context, const ExtParameters& extParams); |
| virtual ~TessellationShaderInvarianceRule6Test(); |
| |
| protected: |
| /* Protected methods */ |
| unsigned int getAmountOfIterations(); |
| |
| void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, |
| bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, |
| _tessellation_shader_vertex_ordering* out_vertex_ordering, |
| unsigned int* out_result_buffer_size); |
| |
| std::string getTECode(unsigned int n_iteration); |
| void verifyResultData(const void** all_iterations_data); |
| |
| private: |
| /* Private type definitions */ |
| typedef struct _test_iteration |
| { |
| glw::GLfloat inner_tess_levels[2]; |
| glw::GLfloat outer_tess_levels[4]; |
| _tessellation_primitive_mode primitive_mode; |
| _tessellation_shader_vertex_ordering vertex_ordering; |
| |
| unsigned int n_vertices; |
| |
| _test_iteration() |
| { |
| memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); |
| memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); |
| |
| primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; |
| vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN; |
| |
| n_vertices = 0; |
| } |
| } _test_iteration; |
| |
| typedef std::vector<_test_iteration> _test_iterations; |
| typedef _test_iterations::const_iterator _test_iterations_const_iterator; |
| |
| /* Private methods */ |
| void deinitTestIterations(); |
| _test_iteration& getTestForIteration(unsigned int n_iteration); |
| void initTestIterations(); |
| |
| /* Private fields */ |
| _test_iterations m_test_triangles_iterations; |
| _test_iterations m_test_quads_iterations; |
| }; |
| |
| /** Implementation of Test Case 48 |
| * |
| * Make sure that invariance rule 7 is adhered to. Using a program object |
| * consisting of a fragment/tessellation control/tessellation evaluation/ |
| * vertex shaders, tessellate a number of triangles/quads geometry |
| * with different vertex spacing input layout qualifiers. For each such |
| * case, the test should verify that modification of a single outer tessellation |
| * level only affects tessellation coordinates generated for a corresponding |
| * edge. Verification should be carried out by capturing vertices generated for |
| * tessellation evaluation stage and making sure that each iteration defines |
| * exactly the same set of triangles connecting inner and outer edge of the |
| * tessellated geometry for all but the modified edge. |
| **/ |
| class TessellationShaderInvarianceRule7Test : public TessellationShaderInvarianceBaseTest |
| { |
| public: |
| /* Public methods */ |
| TessellationShaderInvarianceRule7Test(Context& context, const ExtParameters& extParams); |
| virtual ~TessellationShaderInvarianceRule7Test(); |
| |
| protected: |
| /* Protected methods */ |
| unsigned int getAmountOfIterations(); |
| |
| void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, |
| bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, |
| _tessellation_shader_vertex_ordering* out_vertex_ordering, |
| unsigned int* out_result_buffer_size); |
| |
| std::string getTECode(unsigned int n_iteration); |
| void verifyResultData(const void** all_iterations_data); |
| |
| private: |
| /* Private type definitions */ |
| typedef struct _test_iteration |
| { |
| glw::GLfloat inner_tess_levels[2]; |
| glw::GLfloat outer_tess_levels[4]; |
| _tessellation_primitive_mode primitive_mode; |
| _tessellation_shader_vertex_ordering vertex_ordering; |
| |
| bool is_base_iteration; |
| unsigned int n_modified_outer_tess_level; |
| unsigned int n_vertices; |
| |
| _test_iteration() |
| { |
| memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); |
| memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); |
| |
| primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; |
| vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN; |
| |
| is_base_iteration = false; |
| n_modified_outer_tess_level = 0; |
| n_vertices = 0; |
| } |
| } _test_iteration; |
| |
| typedef std::vector<_test_iteration> _test_iterations; |
| typedef _test_iterations::const_iterator _test_iterations_const_iterator; |
| |
| /* Private methods */ |
| void deinitTestIterations(); |
| |
| unsigned int getTestIterationIndex(bool is_triangles_iteration, const float* inner_tess_levels, |
| const float* outer_tess_levels, |
| _tessellation_shader_vertex_ordering vertex_ordering, |
| unsigned int n_modified_outer_tess_level); |
| |
| _test_iteration& getTestForIteration(unsigned int n_iteration); |
| void initTestIterations(); |
| |
| bool isTriangleDefinedInVertexDataSet(const float* base_triangle_data, const float* vertex_data, |
| unsigned int vertex_data_n_vertices); |
| |
| bool isVertexDefined(const float* vertex_data, unsigned int n_vertices, const float* vertex_data_seeked, |
| unsigned int n_vertex_data_seeked_components); |
| |
| /* Private fields */ |
| _test_iterations m_test_triangles_iterations; |
| _test_iterations m_test_quads_iterations; |
| }; |
| |
| } // namespace glcts |
| |
| #endif // _ESEXTCTESSELLATIONSHADERINVARIANCE_HPP |