blob: e78d24c4180addeaa6cea6d46fbc4acf4678f663 [file] [log] [blame]
#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