blob: 3e9425175306598ae575cd7e8a8342430220dad6 [file] [log] [blame]
#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<glw::GLfloat> 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<glw::GLfloat> 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<float> 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