blob: 3fc4ad7be1619074bfbce6029340337435d1eeec [file] [log] [blame]
#ifndef _ESEXTCGEOMETRYSHADERADJACENCY_HPP
#define _ESEXTCGEOMETRYSHADERADJACENCY_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"
namespace glcts
{
/* Test Implementation of "Group 2" from CTS_EXT_geometry_shader. Description follows:
*
* 1. Make sure that draw calls properly accept and pass the "lines with
* adjacency" data to a geometry shader. The geometry shader should then
* forward adjacent line segments into one transform feedback buffer object
* and actual line segments into another one.
*
* Category: API;
* Functional Test
*
* Create a program object and a fragment, geometry and vertex shader
* objects, as well as a buffer object and a transform feedback object.
*
* The vertex shader object can be boilerplate.
*
* The geometry shader should define:
*
* * output vec4 variable called out_adjacent_geometry;
* * output vec4 variable called out_geometry;
*
* It should take lines_adjacency data and emit two adjacent line segments
* to out_adjacent_geometry variable and one "actual" line segment to
* out_geometry. Since there will be two adjacent segments and only one
* "actual" line segment, the missing line segment should use (0, 0, 0, 0)
* coordinates for its start/end points.
*
* The fragment shader object can have a boilerplate implementation.
*
* Compile the shaders, attach them to the program object, link the program
* object.
*
* Generate and bind a vertex array object.
*
* Initialize a buffer object (A) to have enough space to hold information
* for 3 coordinates * 4 vertex locations * 2 (output primitive
* type-specific data topology). The data should describe 4 lines (including
* adjacency data) that - as a whole - make a rectangle from (-1, -1, 0) to
* (1, 1, 0). The buffer data should then be bound to an attribute, whose
* index corresponds to location of the input in variable. Enable the vertex
* attribute array for this index.
*
* Initialize a buffer object (B) to have enough space to hold result
* adjacent data information.
*
* Initialize a buffer object (C) to have enough space to hold result
* geometry information.
*
* Configure transform feedback so that it captures aforementioned data
* written by geometry shader and stores:
*
* * values stored into out_adjacency_geometry in buffer object B;
* * values stored into out_geometry in buffer object C;
*
* Use separate transform feedback mode. Enable transform feedback. Enable
* rasterizer discard mode.
*
* Finally, issue a draw call in GL_LINES_ADJACENCY_EXT mode for 8 points.
*
* Map the buffer objects to client space. The test is assumed to have
* passed if the mapped buffer objects contain correct data.
*
* NOTE: This test should verify both arrayed and indexed draw calls work
* correctly.
*
*
* 2. Make sure that draw calls properly accept and pass the "lines with
* adjacency" data to a vertex shader without the adjacency information,
* assuming there is no geometry shader defined for the pipeline.
*
* Category: API;
* Functional Test.
*
* Create a program object and a fragment and vertex shader object, as well
* as a buffer object and a transform feedback object.
*
* The fragment shader object can have a boilerplate implementation.
*
* The vertex shader object should define a single input vec3 variable
* called in_vertex and a single output vec3 variable called out_vertex. It
* should write data from in_vertex in an unchanged form to out_vertex.
*
* Compile the shaders, attach them to the program object, link the program
* object.
*
* Bind the vertex array object.
*
* Initialize a buffer object to have enough space to hold information about
* 3-component floating point-based 32 vertices. The data should represent 4
* lines (including adjacency data) that - as a whole - make a rectangle
* from (-1, -1, 0) to (1, 1, 0). The buffer data should then be bound to an
* attribute, whose index corresponds to location of the input in variable.
* Enable the vertex attribute array for this index..
*
* Initialize another buffer object to have enough space to hold information
* about at most 32 vertices, each consisting of 3 floating-point components.
* Configure transform feed-back so that it captures data written by vertex
* shader output variable to this buffer object. Enable transform feedback.
* Enable rasterizer discard mode.
*
* Finally, issue a draw call in GL_LINES_ADJACENCY_EXT mode for 8 points.
*
* Map the buffer object to client space. The test is assumed to have passed
* if the result data corresponds to locations of 8 vertices making up the
* rectangle *without* the adjacency data.
*
*
* 3. Make sure that draw calls properly accept and pass the "line strips with
* adjacency" data to a geometry shader, if there is one included in the
* pipeline.
*
* Category: API;
* Functional Test.
*
* Modify test case 2.1 accordingly to work on "line strips with adjacency"
* data instead of "lines with adjacency" data.
*
*
* 4. Make sure that draw calls properly accept and pass the "line strips with
* adjacency" data to a vertex shader without the adjacency information,
* assuming there is no geometry shader defined for the pipeline.
*
* Category: API;
* Functional Test.
*
* Modify test case 2.2 accordingly to work on "line strips with adjacency"
* data instead of "lines with adjacency" data.
*
*
* 5. Make sure that draw calls properly accept and pass the "triangles with
* adjacency" data to a geometry shader, if there is one included in the
* pipeline.
*
* Category: API;
* Functional Test.
*
* Modify test case 2.1 accordingly to work on "triangles with adjacency"
* data instead of "lines with adjacency" data.
*
*
* 6. Make sure that draw calls properly accept and pass the "triangles with
* adjacency" data to a vertex shader without the adjacency information,
* assuming there is no geometry shader defined for the pipeline.
*
* Category: API;
* Functional Test.
*
* Modify test case 2.2 accordingly to work on "triangles with adjacency"
* data instead of "lines with adjacency" data
*
*
* 7. Make sure that draw calls properly accept and pass the "triangle strips
* with adjacency" data to a geometry shader, if there is one included in
* the pipeline.
*
* Category: API;
* Functional Test.
*
* Modify test case 2.1 accordingly to work on "triangle strips with
* adjacency" data instead of "lines with adjacency" data.
*
*
* 8. Make sure that draw calls properly accept and pass the "triangle strips
* with adjacency" data to a vertex shader without the adjacency information,
* assuming there is no geometry shader defined for the pipeline.
*
* Category: API;
* Functional Test.
*
* Modify test case 2.2 accordingly to work on "triangle strips with
* adjacency" data instead of "lines with adjacency" data.
*
**/
/* Helper class for storing point data */
struct AdjacencyGridPoint
{
/* Public variables */
glw::GLuint index;
glw::GLfloat x;
glw::GLfloat y;
};
/* Helper class for storing line data */
struct AdjacencyGridLineSegment
{
/* Public variables */
AdjacencyGridPoint* m_point_end;
AdjacencyGridPoint* m_point_end_adjacent;
AdjacencyGridPoint* m_point_start;
AdjacencyGridPoint* m_point_start_adjacent;
};
/* Helper class for storing strip data */
class AdjacencyGridStrip
{
public:
/* Public metods */
AdjacencyGridStrip();
virtual ~AdjacencyGridStrip();
/* Public variables */
glw::GLuint m_n_points;
AdjacencyGridPoint* m_points;
};
/* Helper class for storing triangle data */
class AdjacencyGridTriangle
{
public:
/* Public variables */
AdjacencyGridPoint* m_vertex_x;
AdjacencyGridPoint* m_vertex_x_adjacent;
AdjacencyGridPoint* m_vertex_y;
AdjacencyGridPoint* m_vertex_y_adjacent;
AdjacencyGridPoint* m_vertex_z;
AdjacencyGridPoint* m_vertex_z_adjacent;
};
/* Helper class for storing grid data */
class AdjacencyGrid
{
public:
/* Public metods */
AdjacencyGrid(void);
virtual ~AdjacencyGrid(void);
/* Public variables */
AdjacencyGridLineSegment* m_line_segments;
AdjacencyGridStrip m_line_strip;
AdjacencyGridPoint* m_points;
AdjacencyGridTriangle* m_triangles;
AdjacencyGridStrip m_triangle_strip;
glw::GLuint m_n_points;
glw::GLuint m_n_segments;
glw::GLuint m_n_triangles;
};
/* Helper class for storing test data */
class AdjacencyTestData
{
public:
/* Public metods */
AdjacencyTestData(void);
virtual ~AdjacencyTestData(void);
/* Public variables */
const char* m_gs_code;
glw::GLenum m_mode;
glw::GLuint m_n_vertices;
AdjacencyGrid* m_grid;
glw::GLuint m_geometry_bo_size;
glw::GLuint m_index_data_bo_size;
glw::GLuint m_vertex_data_bo_size;
glw::GLfloat* m_expected_adjacency_geometry;
glw::GLfloat* m_expected_geometry;
glw::GLuint* m_index_data;
glw::GLenum m_tf_mode;
glw::GLfloat* m_vertex_data;
};
/* Test class implementation */
class GeometryShaderAdjacency : public TestCaseBase
{
public:
/* Public methods */
GeometryShaderAdjacency(Context& context, const ExtParameters& extParams, const char* name, const char* description,
AdjacencyTestData& testData);
virtual ~GeometryShaderAdjacency()
{
}
virtual void deinit(void);
virtual IterateResult iterate(void);
protected:
/* Protected methods */
void initTest(void);
const char* getFragmentShaderCode();
const char* getVertexShaderCode();
private:
/* Private variables */
glw::GLuint m_adjacency_geometry_bo_id;
glw::GLuint m_fs_id;
glw::GLuint m_geometry_bo_id;
glw::GLuint m_gs_id;
glw::GLuint m_index_data_bo_id;
glw::GLuint m_vertex_data_bo_id;
glw::GLuint m_po_id;
AdjacencyTestData& m_test_data;
glw::GLuint m_vao_id;
glw::GLuint m_vs_id;
/* Private constants */
glw::GLuint m_components_input;
glw::GLfloat m_epsilon;
glw::GLuint m_position_attribute_location;
};
} // namespace glcts
#endif // _ESEXTCGEOMETRYSHADERADJACENCY_HPP