1 #ifndef _ESEXTCGEOMETRYSHADERADJACENCY_HPP 2 #define _ESEXTCGEOMETRYSHADERADJACENCY_HPP 3 /*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 2014-2016 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ /*! 22 * \file 23 * \brief 24 */ /*-------------------------------------------------------------------*/ 25 26 #include "../esextcTestCaseBase.hpp" 27 28 namespace glcts 29 { 30 /* Test Implementation of "Group 2" from CTS_EXT_geometry_shader. Description follows: 31 * 32 * 1. Make sure that draw calls properly accept and pass the "lines with 33 * adjacency" data to a geometry shader. The geometry shader should then 34 * forward adjacent line segments into one transform feedback buffer object 35 * and actual line segments into another one. 36 * 37 * Category: API; 38 * Functional Test 39 * 40 * Create a program object and a fragment, geometry and vertex shader 41 * objects, as well as a buffer object and a transform feedback object. 42 * 43 * The vertex shader object can be boilerplate. 44 * 45 * The geometry shader should define: 46 * 47 * * output vec4 variable called out_adjacent_geometry; 48 * * output vec4 variable called out_geometry; 49 * 50 * It should take lines_adjacency data and emit two adjacent line segments 51 * to out_adjacent_geometry variable and one "actual" line segment to 52 * out_geometry. Since there will be two adjacent segments and only one 53 * "actual" line segment, the missing line segment should use (0, 0, 0, 0) 54 * coordinates for its start/end points. 55 * 56 * The fragment shader object can have a boilerplate implementation. 57 * 58 * Compile the shaders, attach them to the program object, link the program 59 * object. 60 * 61 * Generate and bind a vertex array object. 62 * 63 * Initialize a buffer object (A) to have enough space to hold information 64 * for 3 coordinates * 4 vertex locations * 2 (output primitive 65 * type-specific data topology). The data should describe 4 lines (including 66 * adjacency data) that - as a whole - make a rectangle from (-1, -1, 0) to 67 * (1, 1, 0). The buffer data should then be bound to an attribute, whose 68 * index corresponds to location of the input in variable. Enable the vertex 69 * attribute array for this index. 70 * 71 * Initialize a buffer object (B) to have enough space to hold result 72 * adjacent data information. 73 * 74 * Initialize a buffer object (C) to have enough space to hold result 75 * geometry information. 76 * 77 * Configure transform feedback so that it captures aforementioned data 78 * written by geometry shader and stores: 79 * 80 * * values stored into out_adjacency_geometry in buffer object B; 81 * * values stored into out_geometry in buffer object C; 82 * 83 * Use separate transform feedback mode. Enable transform feedback. Enable 84 * rasterizer discard mode. 85 * 86 * Finally, issue a draw call in GL_LINES_ADJACENCY_EXT mode for 8 points. 87 * 88 * Map the buffer objects to client space. The test is assumed to have 89 * passed if the mapped buffer objects contain correct data. 90 * 91 * NOTE: This test should verify both arrayed and indexed draw calls work 92 * correctly. 93 * 94 * 95 * 2. Make sure that draw calls properly accept and pass the "lines with 96 * adjacency" data to a vertex shader without the adjacency information, 97 * assuming there is no geometry shader defined for the pipeline. 98 * 99 * Category: API; 100 * Functional Test. 101 * 102 * Create a program object and a fragment and vertex shader object, as well 103 * as a buffer object and a transform feedback object. 104 * 105 * The fragment shader object can have a boilerplate implementation. 106 * 107 * The vertex shader object should define a single input vec3 variable 108 * called in_vertex and a single output vec3 variable called out_vertex. It 109 * should write data from in_vertex in an unchanged form to out_vertex. 110 * 111 * Compile the shaders, attach them to the program object, link the program 112 * object. 113 * 114 * Bind the vertex array object. 115 * 116 * Initialize a buffer object to have enough space to hold information about 117 * 3-component floating point-based 32 vertices. The data should represent 4 118 * lines (including adjacency data) that - as a whole - make a rectangle 119 * from (-1, -1, 0) to (1, 1, 0). The buffer data should then be bound to an 120 * attribute, whose index corresponds to location of the input in variable. 121 * Enable the vertex attribute array for this index.. 122 * 123 * Initialize another buffer object to have enough space to hold information 124 * about at most 32 vertices, each consisting of 3 floating-point components. 125 * Configure transform feed-back so that it captures data written by vertex 126 * shader output variable to this buffer object. Enable transform feedback. 127 * Enable rasterizer discard mode. 128 * 129 * Finally, issue a draw call in GL_LINES_ADJACENCY_EXT mode for 8 points. 130 * 131 * Map the buffer object to client space. The test is assumed to have passed 132 * if the result data corresponds to locations of 8 vertices making up the 133 * rectangle *without* the adjacency data. 134 * 135 * 136 * 3. Make sure that draw calls properly accept and pass the "line strips with 137 * adjacency" data to a geometry shader, if there is one included in the 138 * pipeline. 139 * 140 * Category: API; 141 * Functional Test. 142 * 143 * Modify test case 2.1 accordingly to work on "line strips with adjacency" 144 * data instead of "lines with adjacency" data. 145 * 146 * 147 * 4. Make sure that draw calls properly accept and pass the "line strips with 148 * adjacency" data to a vertex shader without the adjacency information, 149 * assuming there is no geometry shader defined for the pipeline. 150 * 151 * Category: API; 152 * Functional Test. 153 * 154 * Modify test case 2.2 accordingly to work on "line strips with adjacency" 155 * data instead of "lines with adjacency" data. 156 * 157 * 158 * 5. Make sure that draw calls properly accept and pass the "triangles with 159 * adjacency" data to a geometry shader, if there is one included in the 160 * pipeline. 161 * 162 * Category: API; 163 * Functional Test. 164 * 165 * Modify test case 2.1 accordingly to work on "triangles with adjacency" 166 * data instead of "lines with adjacency" data. 167 * 168 * 169 * 6. Make sure that draw calls properly accept and pass the "triangles with 170 * adjacency" data to a vertex shader without the adjacency information, 171 * assuming there is no geometry shader defined for the pipeline. 172 * 173 * Category: API; 174 * Functional Test. 175 * 176 * Modify test case 2.2 accordingly to work on "triangles with adjacency" 177 * data instead of "lines with adjacency" data 178 * 179 * 180 * 7. Make sure that draw calls properly accept and pass the "triangle strips 181 * with adjacency" data to a geometry shader, if there is one included in 182 * the pipeline. 183 * 184 * Category: API; 185 * Functional Test. 186 * 187 * Modify test case 2.1 accordingly to work on "triangle strips with 188 * adjacency" data instead of "lines with adjacency" data. 189 * 190 * 191 * 8. Make sure that draw calls properly accept and pass the "triangle strips 192 * with adjacency" data to a vertex shader without the adjacency information, 193 * assuming there is no geometry shader defined for the pipeline. 194 * 195 * Category: API; 196 * Functional Test. 197 * 198 * Modify test case 2.2 accordingly to work on "triangle strips with 199 * adjacency" data instead of "lines with adjacency" data. 200 * 201 **/ 202 203 /* Helper class for storing point data */ 204 struct AdjacencyGridPoint 205 { 206 /* Public variables */ 207 glw::GLuint index; 208 glw::GLfloat x; 209 glw::GLfloat y; 210 }; 211 212 /* Helper class for storing line data */ 213 struct AdjacencyGridLineSegment 214 { 215 /* Public variables */ 216 AdjacencyGridPoint* m_point_end; 217 AdjacencyGridPoint* m_point_end_adjacent; 218 AdjacencyGridPoint* m_point_start; 219 AdjacencyGridPoint* m_point_start_adjacent; 220 }; 221 222 /* Helper class for storing strip data */ 223 class AdjacencyGridStrip 224 { 225 public: 226 /* Public metods */ 227 AdjacencyGridStrip(); 228 virtual ~AdjacencyGridStrip(); 229 230 /* Public variables */ 231 glw::GLuint m_n_points; 232 AdjacencyGridPoint* m_points; 233 }; 234 235 /* Helper class for storing triangle data */ 236 class AdjacencyGridTriangle 237 { 238 public: 239 /* Public variables */ 240 AdjacencyGridPoint* m_vertex_x; 241 AdjacencyGridPoint* m_vertex_x_adjacent; 242 AdjacencyGridPoint* m_vertex_y; 243 AdjacencyGridPoint* m_vertex_y_adjacent; 244 AdjacencyGridPoint* m_vertex_z; 245 AdjacencyGridPoint* m_vertex_z_adjacent; 246 }; 247 248 /* Helper class for storing grid data */ 249 class AdjacencyGrid 250 { 251 public: 252 /* Public metods */ 253 AdjacencyGrid(void); 254 virtual ~AdjacencyGrid(void); 255 256 /* Public variables */ 257 AdjacencyGridLineSegment* m_line_segments; 258 AdjacencyGridStrip m_line_strip; 259 AdjacencyGridPoint* m_points; 260 AdjacencyGridTriangle* m_triangles; 261 AdjacencyGridStrip m_triangle_strip; 262 263 glw::GLuint m_n_points; 264 glw::GLuint m_n_segments; 265 glw::GLuint m_n_triangles; 266 }; 267 268 /* Helper class for storing test data */ 269 class AdjacencyTestData 270 { 271 public: 272 /* Public metods */ 273 AdjacencyTestData(void); 274 virtual ~AdjacencyTestData(void); 275 276 /* Public variables */ 277 const char* m_gs_code; 278 glw::GLenum m_mode; 279 glw::GLuint m_n_vertices; 280 AdjacencyGrid* m_grid; 281 glw::GLuint m_geometry_bo_size; 282 glw::GLuint m_index_data_bo_size; 283 glw::GLuint m_vertex_data_bo_size; 284 glw::GLfloat* m_expected_adjacency_geometry; 285 glw::GLfloat* m_expected_geometry; 286 glw::GLuint* m_index_data; 287 glw::GLenum m_tf_mode; 288 glw::GLfloat* m_vertex_data; 289 }; 290 291 /* Test class implementation */ 292 class GeometryShaderAdjacency : public TestCaseBase 293 { 294 public: 295 /* Public methods */ 296 GeometryShaderAdjacency(Context& context, const ExtParameters& extParams, const char* name, const char* description, 297 AdjacencyTestData& testData); 298 ~GeometryShaderAdjacency()299 virtual ~GeometryShaderAdjacency() 300 { 301 } 302 303 virtual void deinit(void); 304 virtual IterateResult iterate(void); 305 306 protected: 307 /* Protected methods */ 308 void initTest(void); 309 const char* getFragmentShaderCode(); 310 const char* getVertexShaderCode(); 311 312 private: 313 /* Private variables */ 314 glw::GLuint m_adjacency_geometry_bo_id; 315 glw::GLuint m_fs_id; 316 glw::GLuint m_geometry_bo_id; 317 glw::GLuint m_gs_id; 318 glw::GLuint m_index_data_bo_id; 319 glw::GLuint m_vertex_data_bo_id; 320 glw::GLuint m_po_id; 321 AdjacencyTestData& m_test_data; 322 glw::GLuint m_vao_id; 323 glw::GLuint m_vs_id; 324 325 /* Private constants */ 326 glw::GLuint m_components_input; 327 glw::GLfloat m_epsilon; 328 glw::GLuint m_position_attribute_location; 329 }; 330 331 } // namespace glcts 332 333 #endif // _ESEXTCGEOMETRYSHADERADJACENCY_HPP 334