1 #ifndef _ESEXTCTESSELLATIONSHADERTCTE_HPP 2 #define _ESEXTCTESSELLATIONSHADERTCTE_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 "esextcTessellationShaderUtils.hpp" 28 #include "gluShaderUtil.hpp" 29 #include "tcuDefs.hpp" 30 31 namespace glcts 32 { 33 34 /** A DEQP CTS test group that collects all tests that verify various 35 * interactions between tessellation control and tessellation evaluation 36 * shaders 37 */ 38 class TessellationShaderTCTETests : public glcts::TestCaseGroupBase 39 { 40 public: 41 /* Public methods */ 42 TessellationShaderTCTETests(glcts::Context& context, const ExtParameters& extParams); 43 ~TessellationShaderTCTETests(void)44 virtual ~TessellationShaderTCTETests(void) 45 { 46 } 47 48 void init(void); 49 50 private: 51 /* Private methods */ 52 TessellationShaderTCTETests(const TessellationShaderTCTETests& other); 53 TessellationShaderTCTETests& operator=(const TessellationShaderTCTETests& other); 54 }; 55 56 /** Implementation of Test Case 50 57 * 58 * Make sure that tessellation control shader can correctly read per-vertex 59 * values, as modified by a vertex shader. Verify per-vertex gl_Position 60 * and gl_PointSize values are assigned values as in vertex shader. 61 * Make sure that per-vertex & per-patch outputs written to in tessellation 62 * control shader can be correctly read by tessellation evaluation shader. 63 * Pay special attention to gl_Position and gl_PointSize. 64 * Make sure that per-vertex output variables of a tessellation evaluation 65 * shader can be correctly read by a geometry shader. 66 * 67 * Note: gl_PointSize should only be passed down the rendering pipeline and 68 * then verified by the test if GL_EXT_tessellation_point_size 69 * extension support is reported. 70 * 71 * 1. The test should run in three iterations: 72 * 1a. Vertex + TC + TE stages should be defined; 73 * 1b. Vertex + TC + TE + GS stages should be defined (if geometry 74 * shaders are supported); 75 * 2. The test should be run for all three tessellator primitive types, 76 * with inner and outer tessellation levels set to reasonably small 77 * values but not equal to 1 for the levels that affect the tessellation 78 * process for the primitive type considered. 79 * 3. Vertex shader should set: 80 * 3a. gl_Position to vec4(gl_VertexID); 81 * 3b. gl_PointSize to 1.0 / float(gl_VertexID); 82 * 3c. an output vec4 variable to: 83 * vec4(gl_VertexID, gl_VertexID * 0.5, gl_VertexID * 0.25, gl_VertexID * 0.125); 84 * 3d. an outpt ivec4 variable to: 85 * ivec4(gl_VertexID, gl_VertexID + 1, gl_VertexID + 2, gl_VertexID + 3); 86 * 4. TC shader should define corresponding input variables and patch 87 * their contents through (for gl_InvocationID invocation) to 88 * differently named output variables; 89 * gl_Position and gl_PointSize values for the invocation 90 * considered should also be forwarded. 91 * One of the invocations for each patch should also set a vec4 92 * and ivec4 per-patch variables to values as above, multiplied by two. 93 * 5. TE shader should define corresponding input variables and patch 94 * their contents through to a differently named output variables; 95 * gl_Position, gl_PointSize, gl_TessLevelOuter and gl_TessLevelInner 96 * values for the primitive being processed should also be forwarded. 97 * If TC is present in the pipeline, TE stage should also define 98 * two new output variables and set them to per-patch variable 99 * values, as set by TC. 100 * 6. Geometry shader should define corresponding input variables and 101 * patch their contents through to a differently named output 102 * variables; 103 * 7. Test implementation should retrieve the captured data once a single 104 * instance of geometry is rendered and verify it. 105 * 106 **/ 107 class TessellationShaderTCTEDataPassThrough : public TestCaseBase 108 { 109 public: 110 /* Public methods */ 111 TessellationShaderTCTEDataPassThrough(Context& context, const ExtParameters& extParams); 112 ~TessellationShaderTCTEDataPassThrough(void)113 virtual ~TessellationShaderTCTEDataPassThrough(void) 114 { 115 } 116 117 virtual void deinit(); 118 void initTest(void); 119 virtual IterateResult iterate(void); 120 121 private: 122 /* Private type definitions */ 123 /* Stores all properties of a single test run */ 124 typedef struct _run 125 { 126 glw::GLuint fs_id; 127 glw::GLuint gs_id; 128 glw::GLuint po_id; 129 glw::GLuint tcs_id; 130 glw::GLuint tes_id; 131 glw::GLuint vs_id; 132 133 _tessellation_primitive_mode primitive_mode; 134 unsigned int n_result_vertices_per_patch; 135 136 std::vector<glw::GLfloat> result_tc_pointSize_data; 137 std::vector<_vec4> result_tc_position_data; 138 std::vector<_vec4> result_tc_value1_data; 139 std::vector<_ivec4> result_tc_value2_data; 140 std::vector<_vec4> result_te_patch_data; 141 std::vector<glw::GLfloat> result_te_pointSize_data; 142 std::vector<_vec4> result_te_position_data; 143 144 /* Constructor */ _runglcts::TessellationShaderTCTEDataPassThrough::_run145 _run() 146 { 147 fs_id = 0; 148 gs_id = 0; 149 n_result_vertices_per_patch = 0; 150 po_id = 0; 151 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 152 tcs_id = 0; 153 tes_id = 0; 154 vs_id = 0; 155 } 156 } _run; 157 158 /* Encapsulates all test runs */ 159 typedef std::vector<_run> _runs; 160 typedef _runs::const_iterator _runs_const_iterator; 161 162 /* Private methods */ 163 void deinitTestRun(_run& run); 164 void executeTestRun(_run& run, _tessellation_primitive_mode primitive_mode, bool should_use_geometry_shader, 165 bool should_pass_point_size_data_in_gs, bool should_pass_point_size_data_in_ts); 166 167 /* Private variables */ 168 glw::GLuint m_bo_id; 169 const unsigned int m_n_input_vertices_per_run; 170 _runs m_runs; 171 TessellationShaderUtils* m_utils_ptr; 172 glw::GLuint m_vao_id; 173 }; 174 175 /** Implementation of Test Case 52 176 * 177 * This test should iterate over all vertex ordering / spacing / primitive / 178 * point mode permutations, as well as over a number of inner/outer tessellation 179 * level configurations. 180 * The tessellation evaluation shaders used for the test should: 181 * 182 * - Make sure that up to gl_MaxPatchVertices vertices' data can be read in 183 * a tessellation evaluation shader. 184 * - Make sure gl_Position and gl_PointSize per-vertex variables can be 185 * accessed for all vertices. 186 * 187 * The tessellation control shader used for the test should set iteration- 188 * -specific properties and configure aforementioned per-vertex variables 189 * accordingly. 190 * 191 * Both pipeline objects and program objects should be used for the purpose 192 * of the test. For each case, the test should verify that correct objects 193 * defining tessellation control and tessellation stages are reported. 194 * For program objects' case, the test should also confirm that valid shader 195 * types are reported for TC and TE shader objects. 196 * The test should also verify that no objects are assigned to either 197 * stage by default. 198 * 199 * The test should check that tessellation-specific properties are reported 200 * correctly. 201 * 202 **/ 203 class TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize : public TestCaseBase 204 { 205 public: 206 /* Public methods */ 207 TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize(Context& context, const ExtParameters& extParams); 208 ~TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize(void)209 virtual ~TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize(void) 210 { 211 } 212 213 virtual void deinit(); 214 void initTest(void); 215 virtual IterateResult iterate(void); 216 217 private: 218 /* Private type definitions */ 219 /** Describes a single test run */ 220 typedef struct _run 221 { 222 glw::GLuint fs_id; 223 glw::GLuint fs_program_id; 224 glw::GLuint pipeline_object_id; 225 glw::GLuint po_id; 226 glw::GLuint tc_id; 227 glw::GLuint tc_program_id; 228 glw::GLuint te_id; 229 glw::GLuint te_program_id; 230 glw::GLuint vs_id; 231 glw::GLuint vs_program_id; 232 233 glw::GLfloat inner[2]; 234 glw::GLfloat outer[4]; 235 bool point_mode; 236 _tessellation_primitive_mode primitive_mode; 237 _tessellation_shader_vertex_ordering vertex_ordering; 238 _tessellation_shader_vertex_spacing vertex_spacing; 239 240 std::vector<float> result_pointsize_data; 241 std::vector<_vec4> result_position_data; 242 std::vector<_vec2> result_value1_data; 243 std::vector<_ivec4> result_value2_data; 244 245 /* Constructor */ _runglcts::TessellationShaderTCTEgl_MaxPatchVertices_Position_PointSize::_run246 _run() 247 : fs_id(0) 248 , fs_program_id(0) 249 , pipeline_object_id(0) 250 , po_id(0) 251 , tc_id(0) 252 , tc_program_id(0) 253 , te_id(0) 254 , te_program_id(0) 255 , vs_id(0) 256 , vs_program_id(0) 257 , point_mode(false) 258 , primitive_mode(TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN) 259 , vertex_ordering(TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN) 260 , vertex_spacing(TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN) 261 { 262 memset(inner, 0, sizeof(inner)); 263 memset(outer, 0, sizeof(outer)); 264 } 265 } _run; 266 267 /** Describes a set of test runs */ 268 typedef std::vector<_run> _runs; 269 typedef _runs::const_iterator _runs_const_iterator; 270 271 /* Private methods */ 272 void deinitTestRun(_run& run); 273 std::string getFragmentShaderCode(bool should_accept_pointsize_data); 274 275 std::string getTessellationControlShaderCode(bool should_pass_pointsize_data, const glw::GLfloat* inner_tess_levels, 276 const glw::GLfloat* outer_tess_levels); 277 278 std::string getTessellationEvaluationShaderCode(bool should_pass_pointsize_data, 279 _tessellation_primitive_mode primitive_mode, 280 _tessellation_shader_vertex_ordering vertex_ordering, 281 _tessellation_shader_vertex_spacing vertex_spacing, 282 bool is_point_mode_enabled); 283 284 std::string getVertexShaderCode(bool should_pass_pointsize_data); 285 void initTestRun(_run& run); 286 287 /* Private variables */ 288 glw::GLuint m_bo_id; 289 glw::GLint m_gl_max_patch_vertices_value; 290 glw::GLint m_gl_max_tess_gen_level_value; 291 _runs m_runs; 292 TessellationShaderUtils* m_utils_ptr; 293 glw::GLuint m_vao_id; 294 }; 295 296 /** Implementation of Test Case 36 297 * 298 * Make sure that values of gl_in[] in a tessellation evaluation shader are 299 * taken from output variables of a tessellation control shader if one is 300 * present. This test should verify that the values are not taken from 301 * a vertex shader. 302 * 303 * Technical details: 304 * 305 * 0. A program consisting of vertex, TC and TE stages should be considered. 306 * 1. Vertex shader should output a set of output variables of different types. 307 * 2. TC shader should define exactly the same set of output variables. 308 * The data the shader writes to these variables must be different than 309 * in the vertex shader's case. 310 * 3. TE shader should define these variables as input variables. It should 311 * copy their values to a set of corresponding output variables, which 312 * the test should then validate by means of Transform Feedback. 313 * 314 **/ 315 class TessellationShaderTCTEgl_in : public TestCaseBase 316 { 317 public: 318 /* Public methods */ 319 TessellationShaderTCTEgl_in(Context& context, const ExtParameters& extParams); 320 ~TessellationShaderTCTEgl_in(void)321 virtual ~TessellationShaderTCTEgl_in(void) 322 { 323 } 324 325 virtual void deinit(); 326 void initTest(void); 327 virtual IterateResult iterate(void); 328 329 private: 330 /* Private methods */ 331 void getXFBProperties(const glw::GLchar*** out_names, glw::GLint* out_n_names, glw::GLint* out_xfb_size); 332 333 /* Private variables */ 334 glw::GLuint m_bo_id; 335 glw::GLuint m_fs_id; 336 glw::GLuint m_po_id; 337 glw::GLuint m_tcs_id; 338 glw::GLuint m_tes_id; 339 glw::GLuint m_vao_id; 340 glw::GLuint m_vs_id; 341 }; 342 343 /** Implementation of Test Case 37 344 * 345 * Make sure that gl_TessLevelOuter[] and gl_TessLevelInner[] accessed from 346 * tessellation evaluation shader hold values, as used in tessellation control 347 * shader for a processed patch (assuming tessellation control shader is 348 * present in the pipeline) 349 * Make sure that gl_TessLevelOuter[] and gl_TessLevelInner[] accessed from 350 * tessellation evaluation shader hold patch parameter values, if no 351 * tessellation control shader is present in the pipeline. 352 * Reported values should not be clamped and rounded, owing to active 353 * vertex spacing mode. 354 * 355 * Technical details: 356 * 357 * 0. The test should use two program objects: one defining a TC stage, 358 * the other one should lack a tessellation control shader. 359 * 1. For the first case, the test implementation should check a couple 360 * of different inner/outer tessellation level configurations by reading 361 * them from an uniform that the test will update prior to doing a draw 362 * call. 363 * For the other case, the parameters can be modified using ES API. 364 * 2. TE should output inner and output tessellation levels to a varying, 365 * for which Transform Feedback should be configured. 366 * 3. Test passes if tessellation levels in TE stage match the ones 367 * defined in TC stage. Pay attention to making sure no clamping 368 * or rounding occurs for any vertex spacing mode. 369 * 370 **/ 371 class TessellationShaderTCTEgl_TessLevel : public TestCaseBase 372 { 373 public: 374 /* Public methods */ 375 TessellationShaderTCTEgl_TessLevel(Context& context, const ExtParameters& extParams); 376 ~TessellationShaderTCTEgl_TessLevel(void)377 virtual ~TessellationShaderTCTEgl_TessLevel(void) 378 { 379 } 380 381 virtual void deinit(); 382 void initTest(void); 383 virtual IterateResult iterate(void); 384 385 private: 386 /* Private type definitions */ 387 typedef struct _test_descriptor 388 { 389 _tessellation_test_type type; 390 _tessellation_shader_vertex_spacing vertex_spacing; 391 392 glw::GLuint fs_id; 393 glw::GLuint po_id; 394 glw::GLuint tcs_id; 395 glw::GLuint tes_id; 396 glw::GLuint vs_id; 397 398 glw::GLint inner_tess_levels_uniform_location; 399 glw::GLint outer_tess_levels_uniform_location; 400 _test_descriptorglcts::TessellationShaderTCTEgl_TessLevel::_test_descriptor401 _test_descriptor() 402 { 403 fs_id = 0; 404 po_id = 0; 405 tcs_id = 0; 406 tes_id = 0; 407 vs_id = 0; 408 409 inner_tess_levels_uniform_location = 0; 410 outer_tess_levels_uniform_location = 0; 411 412 type = TESSELLATION_TEST_TYPE_COUNT; 413 vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; 414 } 415 } _test_descriptor; 416 417 typedef std::vector<_test_descriptor> _tests; 418 typedef _tests::const_iterator _tests_const_iterator; 419 420 /* Private methods */ 421 void deinitTestDescriptor(_test_descriptor* test_ptr); 422 423 void initTestDescriptor(_tessellation_test_type test_type, _test_descriptor* out_test_ptr, 424 _tessellation_shader_vertex_spacing vertex_spacing_mode); 425 426 /* Private variables */ 427 glw::GLint m_gl_max_tess_gen_level_value; 428 429 glw::GLuint m_bo_id; 430 _tests m_tests; 431 glw::GLuint m_vao_id; 432 }; 433 434 /** Implementation of Test Case 35 435 * 436 * Make sure that the number of vertices in input patch of a tessellation 437 * evaluation shader is: 438 * 439 * * fixed and equal to tessellation control shader output patch size parameter 440 * from the time the program object was linked last time, should tessellation 441 * control shader be present in the pipeline; 442 * * equal to patch size parameter at the time of a draw call, if there 443 * is no tessellation control shader present in the pipeline. 444 * 445 * Technical details: 446 * 447 * 0. Apart from the two cases described in the test summary, the implementation 448 * should also iterate over a number of different patch size values. 449 * 1. TE shader should save gl_PatchVerticesIn.length() in an output 450 * variable. This variable should be XFBed to a buffer object and then 451 * verified in the actual test. 452 * 453 **/ 454 class TessellationShaderTCTEgl_PatchVerticesIn : public TestCaseBase 455 { 456 public: 457 /* Public methods */ 458 TessellationShaderTCTEgl_PatchVerticesIn(Context& context, const ExtParameters& extParams); 459 ~TessellationShaderTCTEgl_PatchVerticesIn(void)460 virtual ~TessellationShaderTCTEgl_PatchVerticesIn(void) 461 { 462 } 463 464 virtual void deinit(); 465 void initTest(void); 466 virtual IterateResult iterate(void); 467 468 private: 469 /* Private type definitions */ 470 typedef struct _test_descriptor 471 { 472 _tessellation_test_type type; 473 474 glw::GLuint fs_id; 475 glw::GLuint po_id; 476 glw::GLuint tcs_id; 477 glw::GLuint tes_id; 478 glw::GLuint vs_id; 479 480 unsigned int input_patch_size; 481 _test_descriptorglcts::TessellationShaderTCTEgl_PatchVerticesIn::_test_descriptor482 _test_descriptor() 483 { 484 fs_id = 0; 485 po_id = 0; 486 tcs_id = 0; 487 tes_id = 0; 488 vs_id = 0; 489 490 input_patch_size = 0; 491 type = TESSELLATION_TEST_TYPE_COUNT; 492 } 493 } _test_descriptor; 494 495 typedef std::vector<_test_descriptor> _tests; 496 typedef _tests::const_iterator _tests_const_iterator; 497 498 /* Private methods */ 499 void deinitTestDescriptor(_test_descriptor* test_ptr); 500 void initTestDescriptor(_tessellation_test_type test_type, _test_descriptor* out_test_ptr, 501 unsigned int input_patch_size); 502 503 /* Private variables */ 504 glw::GLint m_gl_max_patch_vertices_value; 505 506 glw::GLuint m_bo_id; 507 _tests m_tests; 508 glw::GLuint m_vao_id; 509 }; 510 511 } // namespace glcts 512 513 #endif // _ESEXTCTESSELLATIONSHADERTCTE_HPP 514