blob: cc97c94eca117213e0345ca9da8b2e419e396ca6 [file] [log] [blame]
#ifndef _ESEXTCTESSELLATIONSHADERTESSELLATION_HPP
#define _ESEXTCTESSELLATIONSHADERTESSELLATION_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 tessellation
* functionality for multiple primitive modes at once, as opposed to some
* other tests that are mode-specific.
*/
class TessellationShaderTessellationTests : public glcts::TestCaseGroupBase
{
public:
/* Public methods */
TessellationShaderTessellationTests(glcts::Context &context, const ExtParameters &extParams);
virtual ~TessellationShaderTessellationTests(void)
{
}
void init(void);
private:
/* Private methods */
TessellationShaderTessellationTests(const TessellationShaderTessellationTests &other);
TessellationShaderTessellationTests &operator=(const TessellationShaderTessellationTests &other);
};
/** Implementation of Test Case 24
*
* Make sure that patches, for which relevant outer tessellation levels have
* been defined to zero or less, are discarded by the tessellation
* primitive generator. Confirm that such patches never reach tessellation
* evaluation shader program.
* Cover all three tessellation primitive generator modes (triangles, quads,
* isolines).
* Note that an assumption was made here that TE's primitive id counter
* works on output patches that are generated afresh from data fed by TC,
* meaning XFBed TE-stage gl_PrimitiveID should be a sequential set, and
* XFBed TC-stage gl_PrimitiveID should be missing every 4th and 6th patch
* vertices.
* This is backed by http://www.khronos.org/bugzilla/show_bug.cgi?id=754
*
* Technical details:
*
* 0. If (gl_PrimitiveID % 4) == 0, TC should set all relevant outer
* tessellation levels to 0.
* 1. If (gl_PrimitiveID % 4) == 2, TC should set all relevant outer
* tessellation level to -1.
* 2. If (gl_PrimitiveID % 4) == 1 OR (gl_PrimitiveID % 4) == 3, TC should
* set all relevant outer tessellation levels to 1.
* 3. Inner tessellation level should always be set to 1.
* 4. TC should also set a per-vertex output variable to gl_PrimitiveID
* value.
* 5. TC should also pass gl_PrimitiveID to TE.
* 6. TE should store both pieces of data using Transform Feedback for each
* patch vertex processed. Test passes if the data retrieved is valid.
*
*
**/
class TessellationShaderTessellationInputPatchDiscard : public TestCaseBase
{
public:
/* Public methods */
TessellationShaderTessellationInputPatchDiscard(Context &context, const ExtParameters &extParams);
virtual ~TessellationShaderTessellationInputPatchDiscard(void)
{
}
virtual void deinit(void);
void initTest(void);
virtual IterateResult iterate(void);
private:
/* Private type definitions */
/** Defines a single test pass */
typedef struct _run
{
glw::GLuint po_id;
_tessellation_primitive_mode primitive_mode;
glw::GLuint tc_id;
glw::GLuint te_id;
_run()
{
po_id = 0;
primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
tc_id = 0;
te_id = 0;
}
} _run;
/** Defines a vector of test passes */
typedef std::vector<_run> _runs;
typedef _runs::const_iterator _runs_const_iterator;
/* Private methods */
std::string getTCCode();
std::string getTECode(_tessellation_primitive_mode primitive_mode);
void deinitRun(_run &test);
void initRun(_run &test, _tessellation_primitive_mode primitive_mode);
/* Private variables */
glw::GLuint m_bo_id;
glw::GLuint m_fs_id;
glw::GLuint m_vs_id;
glw::GLuint m_vao_id;
_runs m_runs;
TessellationShaderUtils *m_utils_ptr;
};
/** Implementation for Test Case 18
*
* Make sure that tessellation control shader is fed with correct gl_InvocationID
* values.
* Make sure that tessellation control and tessellation evaluation shaders are
* fed with correct gl_PatchVerticesIn values.
* Make sure that tessellation control and tessellation evaluation shaders are
* fed with correct gl_PrimitiveID values. Make sure restarting a primitive
* topology does not restart primitive counter.
*
* Technical details:
*
* 0. The test to be executed for all three geometry types supported by
* the tessellator. The draw calls used should draw at least a few
* instances of a set of patches generating a few primitives for each type
* considered. Vertex arrayed and indiced draw calls should be tested.
* A few vertices-per-patch configurations should be considered.
*
* 1. Tessellation control shader to pass gl_InvocationID to tessellation
* evaluation shader for XFB, for later inspection. The values captured
* should run from 0 to the last invocation number for particular draw
* call. Whole range should be covered by exactly one appearance of each index.
*
* 2. Tessellation control shader should pass gl_PatchVerticesIn value to
* tessellation evaluation shader. The value passed from TC, as well as
* gl_PatchVerticesIn value exposed to TE should be captured for later
* inspection.
*
* 3. Step 2 should be repeated for gl_PrimitiveID. The test should confirm
* that using a primitive restart index does not reset the counter, when
* indiced draw calls are tested.
**/
class TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID : public TestCaseBase
{
public:
/* Public methods */
TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID(Context &context,
const ExtParameters &extParams);
virtual ~TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID(void)
{
}
virtual void deinit(void);
void initTest(void);
virtual IterateResult iterate(void);
private:
/* Private type definitions */
/** Defines a single test run */
typedef struct _run
{
glw::GLuint bo_indices_id;
unsigned int drawcall_count_multiplier;
bool drawcall_is_indiced;
glw::GLuint drawcall_n_instances;
glw::GLuint n_instances;
glw::GLint n_patch_vertices;
unsigned int n_restart_indices;
unsigned int n_result_vertices;
glw::GLuint po_id;
_tessellation_primitive_mode primitive_mode;
glw::GLuint tc_id;
glw::GLuint te_id;
_run()
{
bo_indices_id = 0;
drawcall_count_multiplier = 0;
drawcall_is_indiced = false;
drawcall_n_instances = 0;
n_result_vertices = 0;
n_instances = 0;
n_patch_vertices = 0;
n_restart_indices = 0;
po_id = 0;
primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
tc_id = 0;
te_id = 0;
}
} _run;
/** Defines a vector of test runs */
typedef std::vector<_run> _runs;
typedef _runs::const_iterator _runs_const_iterator;
/* Private methods */
std::string getTCCode(glw::GLuint n_patch_vertices);
std::string getTECode(_tessellation_primitive_mode primitive_mode);
void deinitRun(_run &run);
void initRun(_run &run, _tessellation_primitive_mode primitive_mode, glw::GLint n_patch_vertices, bool is_indiced,
glw::GLint n_instances, unsigned int drawcall_count_multiplier);
/* Private variables */
glw::GLuint m_bo_id;
glw::GLuint m_fs_id;
glw::GLuint m_vs_id;
glw::GLuint m_vao_id;
_runs m_runs;
TessellationShaderUtils *m_utils_ptr;
};
/** Implementation of Test Case 51
*
* Make sure that coordinates of all triangles generated by fixed-function
* tessellation primitive generator meet the barycentric coordinate requirement
* u + v + w = 1
*
* Consider a few inner/outer tessellation level combinations
* for triangle and quad inputs of a tessellation evaluation shader.
*
* Epsilon: 1e-5. This is dictated by the language in ES 3.0 specification,
* which seems to be the best pick, given that the tessellator is
* a fixed-function unit.
*
* Make sure that gl_TessCoord is not an array.
* Make sure that gl_TessCoord is not accessible for any of the vertices in
* gl_in[].
* Make sure that (u, v, w) coordinates are in range [0, 1] for all
* tessellation primitive modes.
* Make sure that the w coordinate is always zero for "quads" and "isolines"
* tessellation primitive modes.
*
* This test should be executed in two invocations, depending on the test type:
*
* * Without a tessellation control shader, where the patch tessellation levels
* are configured by using glPatchParameterfv() function (*);
* * With a tessellation control shader used to configure the levels;
*
* (*) Only applies to Desktop
*
**/
class TessellationShaderTessellationgl_TessCoord : public TestCaseBase
{
static std::string getTypeName(_tessellation_test_type test_type);
public:
/* Public methods */
TessellationShaderTessellationgl_TessCoord(Context &context, const ExtParameters &extParams,
_tessellation_test_type test_type);
virtual ~TessellationShaderTessellationgl_TessCoord(void)
{
}
virtual void deinit(void);
void initTest(void);
virtual IterateResult iterate(void);
private:
/* Private type definitions */
/** Defines a single test pass */
typedef struct _test_descriptor
{
glw::GLint n_patch_vertices;
glw::GLuint po_id;
_tessellation_primitive_mode primitive_mode;
glw::GLuint tc_id;
glw::GLuint te_id;
glw::GLfloat tess_level_inner[2];
glw::GLfloat tess_level_outer[4];
_tessellation_test_type type;
_tessellation_shader_vertex_spacing vertex_spacing;
glw::GLint inner_tess_level_uniform_location;
glw::GLint outer_tess_level_uniform_location;
_test_descriptor()
{
memset(tess_level_inner, 0, sizeof(tess_level_inner));
memset(tess_level_outer, 0, sizeof(tess_level_outer));
n_patch_vertices = 0;
po_id = 0;
primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN;
tc_id = 0;
te_id = 0;
type = TESSELLATION_TEST_TYPE_UNKNOWN;
vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN;
inner_tess_level_uniform_location = -1;
outer_tess_level_uniform_location = -1;
}
} _test_descriptor;
/** Defines a vector of test passes */
typedef std::vector<_test_descriptor> _tests;
typedef _tests::const_iterator _tests_const_iterator;
/* Private methods */
std::string getTCCode(glw::GLint n_patch_vertices);
std::string getTECode(_tessellation_shader_vertex_spacing vertex_spacing,
_tessellation_primitive_mode primitive_mode);
void deinitTestDescriptor(_test_descriptor &test);
void initTestDescriptor(_test_descriptor &test, _tessellation_shader_vertex_spacing vertex_spacing,
_tessellation_primitive_mode primitive_mode, glw::GLint n_patch_vertices,
const float *inner_tess_levels, const float *outer_tess_levels,
_tessellation_test_type test_type);
/* Private variables */
_tessellation_test_type m_test_type;
glw::GLuint m_bo_id;
glw::GLuint m_broken_ts_id;
glw::GLuint m_fs_id;
glw::GLuint m_vs_id;
glw::GLuint m_vao_id;
_tests m_tests;
TessellationShaderUtils *m_utils_ptr;
};
/* This test class implements the following test cases:
*
* 20. Make sure it is possible to use up to GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT/4
* vec4 input variables in a tessellation control shader.
* Make sure it is possible to use up to GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT/4
* vec4 input variables in a tessellation evaluation shader.
* This test should issue at least one draw call and verify the results to
* make sure the implementation actually supports the maximums it reports.
*
* 21. Make sure it is possible to use up to GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT/4
* vec4 per-vertex output variables in a tessellation control shader.
* Make sure it is possible to use up to GL_MAX_TESS_PATCH_COMPONENTS_EXT/4
* vec4 per-patch output variables in a tessellation control shader.
* Make sure it is possible to use up to GL_MAX_TESS_PATCH_COMPONENTS_EXT/4
* vec4 per-patch input variables in a tessellation evaluation shader.
* Make sure it is possible to use up to GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT/4
* vec4 per-vertex output variables in a tessellation evaluation shader.
*
* NOTE: The test should separately check if a maximum number of per-vertex and
* per-patch output variables used in a tessellation control shader works
* correctly. This is due to a risk that, had both types been used at once,
* the maximum amount of output components supported for tessellation
* control shader GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT may
* have been exceeded for implementations, for which the property is
* not equal to:
*
* (per-vertex output component count multiplied by output patch size +
* + per-patch output component count).
*
* This test should issue at least one draw call and verify the results to
* make sure the implementation actually supports the maximums it reports.
*
* Category: Functional Test.
* Priority: Must-Have
*
* The test is implemented by checking two different cases:
* 1) In first case, it makes sure it is possible to use up to:
* - GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation control shader,
* - GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation control shader,
* - GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation evaluation shader,
* - GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation evaluation shader.
*
* 2) In second case, it makes sure it is possible to use up to:
* - GL_MAX_TESS_PATCH_COMPONENTS_EXT/4 vec4 per-patch variables in tessellation control shader,
* - GL_MAX_TESS_PATCH_COMPONENTS_EXT/4 vec4 per-patch variables in tessellation evaluation shader.
*/
class TessellationShaderTessellationMaxInOut : public TestCaseBase
{
public:
/* Public methods */
TessellationShaderTessellationMaxInOut(Context &context, const ExtParameters &extParams);
virtual ~TessellationShaderTessellationMaxInOut()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* private methods */
void initBufferObjects(void);
void initProgramObjects(void);
void initReferenceValues(void);
void initTest(void);
void retrieveGLConstantValues(void);
bool compareValues(char const *description, glw::GLfloat *reference_values, int n_reference_values);
/* private variables */
glw::GLuint m_po_id_1; /* program object name for case 1 */
glw::GLuint m_po_id_2; /* program object name for case 2 */
glw::GLuint m_fs_id; /* fragment shader object name */
glw::GLuint m_tcs_id_1; /* tessellation control shader object name for case 1 */
glw::GLuint m_tcs_id_2; /* tessellation control shader object name for case 2 */
glw::GLuint m_tes_id_1; /* tessellation evaluation shader object name for case 1 */
glw::GLuint m_tes_id_2; /* tessellation evaluation shader object name for case 2 */
glw::GLuint m_vs_id_1; /* vertex shader object name for case 1 */
glw::GLuint m_vs_id_2; /* vertex shader object name for case 2 */
glw::GLuint m_tf_bo_id_1; /* buffer object name */
glw::GLuint m_tf_bo_id_2; /* buffer object name */
glw::GLuint m_patch_data_bo_id; /* buffer object name for patch submission */
glw::GLuint m_vao_id; /* vertex array object */
glw::GLint m_gl_max_tess_control_input_components_value; /* value of MAX_TESS_CONTROL_INPUT_COMPONENTS */
glw::GLint m_gl_max_tess_control_output_components_value; /* value of MAX_TESS_CONTROL_OUTPUT_COMPONENTS */
glw::GLint m_gl_max_tess_evaluation_input_components_value; /* value of MAX_TESS_EVALUATION_INPUT_COMPONENTS */
glw::GLint m_gl_max_tess_evaluation_output_components_value; /* value of MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */
glw::GLint
m_gl_max_transform_feedback_interleaved_components_value; /* value of MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS */
glw::GLint m_gl_max_tess_patch_components_value; /* value of MAX_TESS_PATCH_COMPONENTS */
glw::GLint m_gl_max_vertex_output_components_value; /* value of MAX_VERTEX_OUTPUT_COMPONENTS */
glw::GLfloat m_ref_patch_attributes[4]; /* reference values for max per-patch attributes case 2 */
glw::GLfloat *m_ref_vertex_attributes; /* reference values for max per-vertex attributes case 1 */
static const char *m_fs_code; /* fragment shader code */
static const char *m_vs_code; /* vertex shader code */
static const char *m_tcs_code_1; /* tessellation control shader code for per vertex components check */
static const char *m_tcs_code_2; /* tessellation control shader code per patch components check */
static const char *m_tes_code_1; /* tessellation evaluation shader code per vertex components check */
static const char *m_tes_code_2; /* tessellation evaluation shader code per patch components check */
char **m_tf_varyings_names; /* transform feedback varyings names array */
};
} // namespace glcts
#endif // _ESEXTCTESSELLATIONSHADERTESSELLATION_HPP