1 #ifndef _ESEXTCGEOMETRYSHADERINPUT_HPP 2 #define _ESEXTCGEOMETRYSHADERINPUT_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 #include <deque> 28 29 namespace glcts 30 { 31 /** Implementation of test case 5.1. Test description follows: 32 * 33 * Make sure that all output variables of a vertex shader can be accessed 34 * under geometry shader's input array variables. 35 * 36 * Category: API; 37 * Functional Test. 38 * 39 * Vertex shader should define: 40 * 41 * - vec2 output variable named vs_gs_a; 42 * - flat ivec4 output variable named vs_gs_b; 43 * 44 * and set them to meaningful vector values (based on gl_VertexID). 45 * 46 * Geometry shader should take triangles on input, output triangles (3 47 * vertices will be emitted) and also define: 48 * 49 * - vec2 output variable named gs_fs_a (and set it to vs_gs_a[i]); 50 * - flat ivec4 output variable named gs_fs_b (and set it to vs_gs_b[i]); 51 * 52 * where i is index of vertex. 53 * 54 * gl_Position should be set as follows: 55 * 56 * 1st vertex) (-1, -1, 0, 1) 57 * 2nd vertex) (-1, 1, 0, 1) 58 * 3rd vertex) (1, 1, 0, 1) 59 * 60 * Vertex attribute arrays should be configured so that vertex shader passes 61 * meaningful values to the geometry shader. 62 * 63 * Use Transform Feedback to check if geometry shader was passed the right 64 * values. Draw a single triangle. The test passes if the captured data 65 * matches the expected values. 66 **/ 67 class GeometryShader_gl_in_ArrayContentsTest : public TestCaseBase 68 { 69 public: 70 /* Public methods */ 71 GeometryShader_gl_in_ArrayContentsTest(Context& context, const ExtParameters& extParams, const char* name, 72 const char* description); 73 ~GeometryShader_gl_in_ArrayContentsTest()74 virtual ~GeometryShader_gl_in_ArrayContentsTest() 75 { 76 } 77 78 virtual void deinit(void); 79 virtual IterateResult iterate(void); 80 81 private: 82 /* Private methods */ 83 void initTest(void); 84 85 /* Private fields */ 86 /* Program and shader ids */ 87 glw::GLuint m_fragment_shader_id; 88 glw::GLuint m_geometry_shader_sized_arrays_id; 89 glw::GLuint m_geometry_shader_unsized_arrays_id; 90 glw::GLuint m_program_object_sized_arrays_id; 91 glw::GLuint m_program_object_unsized_arrays_id; 92 glw::GLuint m_vertex_shader_id; 93 94 /* Shaders' code */ 95 static const glw::GLchar* const m_fragment_shader_code; 96 static const glw::GLchar* const m_geometry_shader_code; 97 static const glw::GLchar* const m_geometry_shader_preamble_code; 98 static const glw::GLchar* const m_vertex_shader_code; 99 100 /* Buffer Object used to store output from transform feedback */ 101 glw::GLuint m_buffer_object_id; 102 103 /* Constants used to calculate and store size of buffer object, that will be used as transform feedback output */ 104 static const unsigned int m_buffer_size; 105 static const unsigned int m_n_bytes_emitted_per_vertex; 106 static const unsigned int m_n_emitted_primitives; 107 static const unsigned int m_n_vertices_emitted_per_primitive; 108 109 /* Vertex array object ID */ 110 glw::GLuint m_vertex_array_object_id; 111 }; 112 113 /** Implementation of test case 5.2. Test description follows: 114 * 115 * Make sure that length of gl_in array is correct for all input primitive 116 * types accepted by a geometry shader. 117 * 118 * Category: API; 119 * Functional Test. 120 * 121 * Consider a set of geometry shaders, where each geometry shader takes an 122 * unique input primitive type, and the set - as a whole - covers all input 123 * primitive types accepted by geometry shaders. Each geometry shader should 124 * output a maximum of 1 point. They should define an output int variable 125 * called in_array_size and set it to gl_in.length(). 126 * 127 * Using transform feed-back, the test should check whether all geometry 128 * shaders are reported correct gl_in array size for all acceptable input 129 * primitive types. 130 **/ 131 class GeometryShader_gl_in_ArrayLengthTest : public TestCaseBase 132 { 133 public: 134 /* Public methods */ 135 GeometryShader_gl_in_ArrayLengthTest(Context& context, const ExtParameters& extParams, const char* name, 136 const char* description); 137 ~GeometryShader_gl_in_ArrayLengthTest()138 virtual ~GeometryShader_gl_in_ArrayLengthTest() 139 { 140 } 141 142 virtual void deinit(void); 143 virtual void init(void); 144 virtual IterateResult iterate(void); 145 146 private: 147 /* Private types */ 148 struct Case 149 { 150 /* Mode to be used for glDrawArrays() call */ 151 glw::GLenum draw_call_mode; 152 /* Amount of vertices to be requested for glDrawArrays() call */ 153 glw::GLint draw_call_n_vertices; 154 /* Transform feed-back mode to use before doing glDrawArrays() call */ 155 glw::GLenum tf_mode; 156 157 /* ID of a fragment shader to be used for the test case */ 158 glw::GLint fs_id; 159 /* ID of a geometry shader to be used for the test case */ 160 glw::GLint gs_id; 161 /* String defining input layout qualifier for the test case. */ 162 const glw::GLchar* input_body_part; 163 /* String defining output layout qualifier for the test case. */ 164 const glw::GLchar* output_body_part; 165 /** ID of a program object to be used for the test case */ 166 glw::GLint po_id; 167 /** ID of a vertex shader to be used for the test case */ 168 glw::GLint vs_id; 169 170 /** Expected gl_in.length() value for the test case */ 171 glw::GLint expected_array_length; 172 }; 173 174 /* Type of container used to group all test cases */ 175 typedef std::deque<Case*> testContainer; 176 177 /* Private methods */ 178 void deinitCase(Case& info); 179 180 void initCase(Case& info, glw::GLenum draw_call_mode, glw::GLint draw_call_n_vertices, 181 glw::GLint expected_array_length, glw::GLenum tf_mode, const glw::GLchar* input_body_part, 182 const glw::GLchar* output_body_part); 183 184 void initCaseProgram(Case& info, const glw::GLchar** captured_varyings, glw::GLuint n_captured_varyings_size); 185 186 void resetCase(Case& info); 187 188 /* Private fields */ 189 /* Shaders */ 190 static const glw::GLchar* const m_vertex_shader_code; 191 192 static const glw::GLchar* const m_geometry_shader_code_input_points; 193 static const glw::GLchar* const m_geometry_shader_code_input_lines; 194 static const glw::GLchar* const m_geometry_shader_code_input_lines_with_adjacency; 195 static const glw::GLchar* const m_geometry_shader_code_input_triangles; 196 static const glw::GLchar* const m_geometry_shader_code_input_triangles_with_adjacency; 197 static const glw::GLchar* const m_geometry_shader_code_main; 198 static const glw::GLchar* const m_geometry_shader_code_output_line_strip; 199 static const glw::GLchar* const m_geometry_shader_code_output_points; 200 static const glw::GLchar* const m_geometry_shader_code_output_triangle_strip; 201 static const glw::GLchar* const m_geometry_shader_code_preamble; 202 203 static const glw::GLchar* const m_fragment_shader_code; 204 205 /* Test cases */ 206 Case m_test_lines; 207 Case m_test_lines_adjacency; 208 Case m_test_lines_adjacency_to_line_strip; 209 Case m_test_points; 210 Case m_test_triangles; 211 Case m_test_triangles_adjacency; 212 Case m_test_triangles_adjacency_to_triangle_strip; 213 214 /* Set of test cases */ 215 testContainer m_tests; 216 217 /* Buffer Object used to store output from transform feedback */ 218 glw::GLuint m_buffer_object_id; 219 220 /* Constants used to calculate and store size of buffer object, that will be used as transform feedback output */ 221 static const glw::GLuint m_buffer_size; 222 static const glw::GLuint m_max_primitive_emitted; 223 224 /* Vertex array object ID */ 225 glw::GLuint m_vertex_array_object_id; 226 }; 227 228 /** Implementation of test case 5.3. Test description follows: 229 * 230 * Make sure geometry shader is passed gl_PointSize value as set by vertex 231 * shader. 232 * 233 * Category: API; 234 * Functional Test. 235 * 236 * NOTE: This test should be skipped if tested GLES implementation does not 237 * support points of sufficiently large sizes. 238 * 239 * Vertex shader should set gl_PointSize variable to 2*(gl_VertexID+1). 240 * 241 * Geometry shader should take points on input and emit 1 point at most. It 242 * should set gl_PointSize to 2*gl_in[0].gl_PointSize. The test will draw 243 * two points, so to have these two points centered on the left and the right 244 * side of the screen-space (assuming result draw buffer is 16px wide), set 245 * gl_Position to: 246 * 247 * 1) (-1 + (4*(1/16))/2, 0, 0, 1) for the first point, given its point size 248 * equal to 4; 249 * 2) ( 1 - (8*(1/16))/2, 0, 0, 1) for the second point, with its point size 250 * set to 8; 251 * 252 * Fragment shader should set the output variable to (1, 1, 1, 1), the 253 * default clear color should be set to (0, 0, 0, 0). 254 * 255 * Color attachment should have a resolution of 16px x 16px. 256 * 257 * The test should clear the color buffer and draw two points. The test 258 * passes if: 259 * 260 * 1) pixel at (2, 8) is (255, 255, 255, 255) 261 * 2) pixel at (14, 8) is (255, 255, 255, 255) 262 * 3) pixel at (6, 8) is (0, 0, 0, 0) 263 * 264 * Assumption: glReadPixels() is called for GL_RGBA format and 265 * GL_UNSIGNED_BYTE type. 266 **/ 267 class GeometryShader_gl_PointSize_ValueTest : public TestCaseBase 268 { 269 public: 270 /* Public methods */ 271 GeometryShader_gl_PointSize_ValueTest(Context& context, const ExtParameters& extParams, const char* name, 272 const char* description); 273 ~GeometryShader_gl_PointSize_ValueTest()274 virtual ~GeometryShader_gl_PointSize_ValueTest() 275 { 276 } 277 278 virtual void deinit(void); 279 virtual void init(void); 280 virtual IterateResult iterate(void); 281 282 private: 283 /* Private fields */ 284 /* Program and shader ids */ 285 glw::GLuint m_fragment_shader_id; 286 glw::GLuint m_geometry_shader_id; 287 glw::GLuint m_program_object_id; 288 glw::GLuint m_vertex_shader_id; 289 290 /* Shaders' code */ 291 static const glw::GLchar* const m_fragment_shader_code; 292 static const glw::GLchar* const m_geometry_shader_code; 293 static const glw::GLchar* const m_vertex_shader_code; 294 295 /* Vertex array object ID */ 296 glw::GLuint m_vertex_array_object_id; 297 298 /* Texture object ID */ 299 glw::GLuint m_color_texture_id; 300 301 /* Framebuffer object ID */ 302 glw::GLuint m_framebuffer_object_id; 303 304 /* Constants used to store properties of framebuffer's color attachment */ 305 static const glw::GLuint m_texture_height; 306 static const glw::GLuint m_texture_pixel_size; 307 static const glw::GLuint m_texture_width; 308 }; 309 310 /** Implementation of test case 5.4. Test description follows: 311 * 312 * Make sure geometry shader is passed gl_Position value as set by vertex shader. 313 * 314 * Category: API; 315 * Functional Test. 316 * 317 * Vertex shader should set gl_Position variable to 318 * (gl_VertexID, gl_VertexID, 0, 1). 319 * 320 * Geometry shader should take points on input and emit 1 point at most. It 321 * should set gl_PointSize to 8. The test will draw eight points. The 322 * geometry shader should set gl_Position to: 323 * 324 * (-1 + 4/32 + gl_in[0].gl_Position / 4, 0, 0, 1) 325 * 326 * Fragment shader should set the output variable to (1, 1, 1, 1), the 327 * default clear color should be set to (0, 0, 0, 0). 328 * 329 * Color attachment should have a resolution of 64px x 64px. 330 * 331 * The test should clear the color buffer and draw eight points. The test 332 * passes if centers of the rendered points at expected locations are lit. 333 **/ 334 class GeometryShader_gl_Position_ValueTest : public TestCaseBase 335 { 336 public: 337 /* Public methods */ 338 GeometryShader_gl_Position_ValueTest(Context& context, const ExtParameters& extParams, const char* name, 339 const char* description); 340 ~GeometryShader_gl_Position_ValueTest()341 virtual ~GeometryShader_gl_Position_ValueTest() 342 { 343 } 344 345 virtual void deinit(void); 346 virtual void init(void); 347 virtual IterateResult iterate(void); 348 349 private: 350 /* Private fields */ 351 /* Program and shader ids */ 352 glw::GLuint m_fragment_shader_id; 353 glw::GLuint m_geometry_shader_id; 354 glw::GLuint m_program_object_id; 355 glw::GLuint m_vertex_shader_id; 356 357 /* Shaders' code */ 358 static const glw::GLchar* const m_fragment_shader_code; 359 static const glw::GLchar* const m_geometry_shader_code; 360 static const glw::GLchar* const m_vertex_shader_code; 361 362 /* Vertex array object ID */ 363 glw::GLuint m_vertex_array_object_id; 364 365 /* Texture object ID */ 366 glw::GLuint m_color_texture_id; 367 368 /* Framebuffer object ID */ 369 glw::GLuint m_framebuffer_object_id; 370 371 /* Constants used to store properties of framebuffer's color attachment */ 372 static const glw::GLuint m_texture_height; 373 static const glw::GLuint m_texture_pixel_size; 374 static const glw::GLuint m_texture_width; 375 }; 376 377 } /* glcts */ 378 379 #endif // _ESEXTCGEOMETRYSHADERINPUT_HPP 380