blob: 957780970b8682f9376b6a54fb976439befbe348 [file] [log] [blame]
#ifndef _ESEXTCGEOMETRYSHADERLINKING_HPP
#define _ESEXTCGEOMETRYSHADERLINKING_HPP
/*-------------------------------------------------------------------------
* OpenGL Conformance Test Suite
* -----------------------------
*
* Copyright (c) 2015-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"
namespace glcts
{
/** Implementation of "Group 17", tests 1 & 2 from CTS_EXT_geometry_shader. Description follows:
*
* 1. Make sure that linking a program object consisting of geometry shader
* object only will fail, assuming the program object is not separable.
*
* Category: API;
* Negative Test.
*
* Create a program object and a compilable geometry shader object.
*
* Attach the geometry shader object to the program object, compile it, link
* the program object.
*
* The test passes if GL_LINK_STATUS for the program object is reported as
* GL_FALSE.
*
* Should separate shader objects be supported, the linking should pass,
* assuming the program object is marked as separable prior to linking.
*
*
* 2. Make sure that linking a program object consisting of fragment and
* geometry shader objects will fail, assuming the program object is not
* separable.
*
* Category: API;
* Negative Test;
*
* Create a program object and a compilable fragment & geometry shader
* objects.
*
* Attach the shader objects to the program object, compile them, link the
* program object.
*
* The test passes if GL_LINK_STATUS for the program object is reported as
* GL_FALSE.
*
* Should separate shader objects be supported, the linking should pass,
* assuming the program object is marked as separable prior to linking.
*
**/
class GeometryShaderIncompleteProgramObjectsTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderIncompleteProgramObjectsTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderIncompleteProgramObjectsTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
typedef struct _run
{
bool use_fs;
bool use_gs;
bool use_separable_po;
explicit _run(bool in_use_fs, bool in_use_gs, bool in_use_separable_po)
{
use_fs = in_use_fs;
use_gs = in_use_gs;
use_separable_po = in_use_separable_po;
}
} _run;
/* Private methods */
void initShaderObjects();
void initTestRuns();
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
std::vector<_run> m_test_runs;
};
/* Implementation of "Group 17", test 3 from CTS_EXT_geometry_shader. Description follows:
*
* 3. Make sure that program objects with a single geometry shader do not link
* if any of the required geometry stage-specific information is missing.
*
* Category: API;
* Negative Test.
*
* Create 5 program objects and a boilerplate fragment & vertex shader
* objects. Consider the following cases for a geometry shader:
*
* - input primitive type is only defined;
* - output primitive type is only defined;
* - maximum output vertex count is defined;
* - input & output primitive types are only defined
* - output primitive type & maximum output vertex count are only defined;
*
* For each of these cases, create a geometry shader with corresponding
* implementation. Each such shader can, but does not necessarily have to,
* compile. Whichever be the case, the test should carry on executing.
*
* Attach aforementioned fragment & vertex shaders to each of the program
* objects. Attach each of the discussed geometry shaders to subsequent
* program objects.
*
* Test succeeds if all program objects failed to link.
*
*/
class GeometryShaderIncompleteGSTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderIncompleteGSTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderIncompleteGSTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
typedef struct _run
{
bool is_input_primitive_type_defined;
bool is_max_vertices_defined;
bool is_output_primitive_type_defined;
explicit _run(bool in_is_input_primitive_type_defined, bool in_is_max_vertices_defined,
bool in_is_output_primitive_type_defined)
{
is_input_primitive_type_defined = in_is_input_primitive_type_defined;
is_max_vertices_defined = in_is_max_vertices_defined;
is_output_primitive_type_defined = in_is_output_primitive_type_defined;
}
} _run;
/* Private methods */
void deinitSOs();
std::string getGeometryShaderCode(const _run& current_run);
void initShaderObjects(const _run& current_run, bool* out_has_fs_compiled_successfully,
bool* out_has_gs_compiled_successfully, bool* out_has_vs_compiled_successfully);
void initTestRuns();
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
std::vector<_run> m_test_runs;
};
/* Implementation of "Group 17", test 4 from CTS_EXT_geometry_shader. Description follows:
*
* 4. Make sure linking fails if input variables of a geometry shader are
* declared as arrays of incorrect size.
*
* Category: API;
* Negative Test.
*
* Consider 5 geometry shaders, each using a different input primitive type
* available for geometry shader's usage. Each geometry shader should define
* an arrayed input variable of size N called invalid, where N is equal to:
*
* (valid size provided the input primitive type) + 1
*
* The geometry shader should output a compatible output primitive type with
* max count set to 1. Rest of the code can be boilerplate, but it must be
* valid.
*
* The vertex shader should output non-arrayed variable invalid, but the
* rest of the code can be boilerplate, provided it is valid.
*
* Same applies for the fragment shader.
*
* 5 program objects, each consisting of a fragment and vertex shaders, as
* well as unique geometry shader, should fail to link.
*
*/
class GeometryShaderInvalidArrayedInputVariablesTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderInvalidArrayedInputVariablesTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderInvalidArrayedInputVariablesTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
void deinitSOs();
std::string getGSCode(glw::GLenum gs_input_primitive_type) const;
std::string getInputPrimitiveTypeQualifier(glw::GLenum gs_input_primitive_type) const;
std::string getSpecializedVSCode() const;
glw::GLuint getValidInputVariableArraySize(glw::GLenum gs_input_primitive_type) const;
void initShaderObjects(glw::GLenum gs_input_primitive_type, bool* out_has_fs_compiled_successfully,
bool* out_has_gs_compiled_successfully, bool* out_has_vs_compiled_successfully);
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 20", test 1 from CTS_EXT_geometry_shader. Description follows:
*
* 1. It is a linking error to declare an output variable in a vertex shader
* and an input variable in a geometry shader, that is of different type
* but has the same qualification and name.
*
* Category: API;
* Negative Test.
*
* Use a boilerplate vertex shader that declares the output variable
* described in summary, a boilerplate geometry shader that declares the
* input variable. A geometry shader should use a different type than the
* vertex shader for the variable declaration, but should use the same
* qualifier.
*
* A boilerplate fragment shader should be used.
*
* Linking is expect to fail under this configuration.
*
*/
class GeometryShaderVSGSVariableTypeMismatchTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderVSGSVariableTypeMismatchTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderVSGSVariableTypeMismatchTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 20", test 2 from CTS_EXT_geometry_shader. Description follows:
*
* 2. It is a linking error to declare an output variable in a vertex shader
* and an input variable in a geometry shader, that is of different
* qualification but has the same type and name.
*
* Category: API;
* Negative Test.
*
* Use a boilerplate vertex shader that declares the output variable
* described in summary, a boilerplate geometry shader that declares the
* input variable. A geometry shader should use a different qualifier than
* the vertex shader for the variable declaration, but should use the same
* type.
*
* A boilerplate fragment shader should be used.
*
* Linking is expected to fail under this configuration.
*
*/
class GeometryShaderVSGSVariableQualifierMismatchTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderVSGSVariableQualifierMismatchTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderVSGSVariableQualifierMismatchTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 20", test 3 from CTS_EXT_geometry_shader. Description follows:
*
* 3. It is a linking error to declare arrayed input variables in a geometry
* size if the array sizes do not match.
*
* Category: API;
* Negative Test.
*
* Create a program object, for which a boilerplate fragment and vertex
* shaders will be used. A geometry shader should also be attached to the
* program object. The shader should include the following incorrect input
* variable declarations:
*
* in vec4 Color1[];
* in vec4 Color2[2];
* in vec4 Color3[3];
*
* Linking of the program object is expected to fail under this configuration.
*
*/
class GeometryShaderVSGSArrayedVariableSizeMismatchTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderVSGSArrayedVariableSizeMismatchTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GeometryShaderVSGSArrayedVariableSizeMismatchTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 20", test 4 from CTS_EXT_geometry_shader. Description follows:
*
* 4. It is a linking error to re-declare gl_FragCoord in a geometry shader.
*
* Category: API;
* Negative Test.
*
* Create a program object, for which a boilerplate fragment and vertex
* shaders will be used. A geometry shader should also be attached to the
* program object. The shader should include the following incorrect input
* variable declaration:
*
* in vec4 gl_FragCoord;
*
* Linking of the program object is expected to fail under this
* configuration.
*
*/
class GeometryShaderFragCoordRedeclarationTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderFragCoordRedeclarationTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderFragCoordRedeclarationTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 20", test 5 from CTS_EXT_geometry_shader. Description follows:
*
* 5. It is a linking error to use the same location for two output variables
* in a geometry shader.
*
* Category: API;
* Negative Test.
*
* Create a program object, for which a boilerplate fragment and vertex
* shaders will be used. A geometry shader should also be attached to the
* program object. The shader should include the following incorrect input
* variable declaration:
*
* layout(location = 2) out vec4 test;
* layout(location = 2) out vec4 test2;
*
* Linking of the program object is expected to fail under this
* configuration.
*
*/
class GeometryShaderLocationAliasingTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderLocationAliasingTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderLocationAliasingTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 23", test 4 from CTS_EXT_geometry_shader. Description follows:
*
* 4. Make sure using more than GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT atomic
* counters from within a geometry shader results in a linking error.
*
* Category: API.
*
* Create a program object. Define a boilerplate fragment and vertex shader
* objects, as well as a geometry shader. The geometry shader should:
*
* - define exactly (GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT+1) atomic counters.
* - take points on input and output a maximum of 1 point;
* - use only one invocation.
* - for each invocation, the shader should increment all atomic counter if
* (gl_PrimitiveIDIn % counter_id) == 0, where counter_id stands for "id" of
* a shader atomic counter, assuming first shader atomic counter has an
* "id" of 1.
* - The shader should set gl_Position to (0, 0, 0, 1) for the vertex that
* will be emitted.
*
* The test succeeds if linking of the program object fails.
*
*/
class GeometryShaderMoreACsInGSThanSupportedTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderMoreACsInGSThanSupportedTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderMoreACsInGSThanSupportedTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
std::string getGSCode();
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 23", test 6 from CTS_EXT_geometry_shader. Description follows:
*
* 6. Make sure using more than GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT
* buffer objects to back up atomic counter storage for geometry shader
* atomic counters results in a linking error.
*
* Category: API.
*
* Create a program object. Define a boilerplate fragment and vertex shader
* objects, as well as a geometry shader. The geometry shader should:
*
* - define exactly (GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT+1) atomic
* counters.
* - take points on input and output a maximum of 1 point;
* - use only one invocation.
* - for each invocation, the shader should increment all atomic counter if
* (gl_PrimitiveIDIn % counter_id) == 0, where counter_id stands for "id" of
* a shader atomic counter, assuming first shader atomic counter has an
* "id" of 1.
* - The shader should set gl_Position to (0, 0, 0, 1) for the vertex that
* will be emitted.
* - Each atomic counter should use a separate buffer object binding.
*
* The test succeeds if linking of the program object fails.
*
*/
class GeometryShaderMoreACBsInGSThanSupportedTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderMoreACBsInGSThanSupportedTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderMoreACBsInGSThanSupportedTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
std::string getGSCode();
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 24", test 1 from CTS_EXT_geometry_shader. Description follows:
*
* 1. Make sure that linking a program object consisting of a fragment,
* geometry and vertex shaders will fail, if geometry shader compilation
* status is GL_FALSE.
*
* Category: API;
* Negative Test.
*
* Create a program object and a fragment, geometry, vertex shader objects:
*
* - Fragment and vertex shader object should be compilable;
* - Geometry shader object should not compile.
*
* Compile all three shaders. Attach them to the program object, try to link
* the program object.
*
* The test passes if GL_LINK_STATUS for the program object is reported as
* GL_FALSE.
*
*/
class GeometryShaderCompilationFailTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderCompilationFailTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderCompilationFailTest()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
private:
/* Private type definition */
/* Private methods */
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
/* Implementation of "Group 24", test 4 from CTS_EXT_geometry_shader. Description follows:
*
* 4. A geometry shader using more input vertices than are available should
* compile, but a program object with the shader attach should not link.
*
* Category: API;
* Negative Test.
*
* Following is a list of vertex count allowed for each geometry shader
* primitive type:
*
* * points - 1;
* * lines - 2;
* * triangles - 3;
* * lines_adjacency - 4;
* * triangles_adjacency - 6;
*
* For each geometry shader primitive type, create a geometry shader object.
* Each shader should output a maximum of a single point. Result vertex
* position should be set to gl_in[X].gl_Position, where X should be equal
* to a relevant value from the list above. This geometry shader must
* successfully compile.
*
* Create 5 program objects and a fragment and vertex shader objects. Each
* of these shaders should use a boilerplate but valid implementation. Each
* program object should be assigned both of these shaders, as well as one
* of the geometry shaders enlisted above, so that all program objects in
* total use up all geometry shaders considered. These program objects
* should fail to link.
*
*/
class GeometryShaderMoreInputVerticesThanAvailableTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderMoreInputVerticesThanAvailableTest(Context& context, const ExtParameters& extParams, const char* name,
const char* description);
virtual ~GeometryShaderMoreInputVerticesThanAvailableTest()
{
}
virtual void deinit();
virtual IterateResult iterate();
private:
/* Private type definition */
/* Private methods */
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint* m_gs_ids;
const glw::GLuint m_number_of_gs;
glw::GLuint* m_po_ids;
glw::GLuint m_vs_id;
glw::GLuint m_vao_id;
};
/* Implementation of "Group 25", test 1 from CTS_EXT_geometry_shader. Description follows:
*
* 1. Transform feedback which captures data from two variables where:
*
* - the first one is set by vertex shader;
* - the second one is set by geometry shader;
*
* should cause linking operation to fail.
*
* Category: API;
* Negative Test.
*
* A vertex shader should declare an output variable out_vs_1 of ivec4 type.
* It should set it to:
*
* (gl_VertexID, gl_VertexID+1, gl_VertexID+2, gl_VertexID+3)
*
* Rest of the code can be boilerplate but must be valid.
*
* A geometry shader should declare an output variable out_gs_1 of vec4
* type. It should set it to:
*
* (gl_VertexID*2, gl_VertexID*2+1, gl_VertexID*2+2, gl_VertexID*2+3)
* (conversions omitted)
*
* The shader should accept points as input and is expected to emit 1 point
* at (0, 0, 0, 1). Rest of the code can be boilerplate but should be valid.
*
* The test should configure the program object to use transform feedback so
* that values the shaders set for both of the variables are captured. The
* test should then attempt to link the program object.
*
* The test passes if GL_LINK_STATUS state of the program object is reported
* to be GL_FALSE after glLinkProgram() call.
*
*/
class GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest(Context& context, const ExtParameters& extParams,
const char* name, const char* description);
virtual ~GeometryShaderTransformFeedbackVertexAndGeometryShaderCaptureTest()
{
}
virtual void deinit();
virtual IterateResult iterate();
private:
/* Private type definition */
/* Private methods */
/* Private variables */
glw::GLuint m_fs_id;
glw::GLuint m_gs_id;
glw::GLuint m_po_id;
glw::GLuint m_vs_id;
};
} // namespace glcts
#endif // _ESEXTCGEOMETRYSHADERLINKING_HPP