1 #ifndef _ESEXTCTESSELLATIONSHADERINVARIANCE_HPP 2 #define _ESEXTCTESSELLATIONSHADERINVARIANCE_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 "glwEnums.hpp" 30 #include "tcuDefs.hpp" 31 32 namespace glcts 33 { 34 35 /** A DEQP CTS test group that collects all tests that verify invariance 36 * conformance. 37 */ 38 class TessellationShaderInvarianceTests : public glcts::TestCaseGroupBase 39 { 40 public: 41 /* Public methods */ 42 TessellationShaderInvarianceTests(glcts::Context& context, const ExtParameters& extParams); 43 ~TessellationShaderInvarianceTests(void)44 virtual ~TessellationShaderInvarianceTests(void) 45 { 46 } 47 48 virtual void init(void); 49 50 private: 51 /* Private methods */ 52 TessellationShaderInvarianceTests(const TessellationShaderInvarianceTests& other); 53 TessellationShaderInvarianceTests& operator=(const TessellationShaderInvarianceTests& other); 54 }; 55 56 /** Base class that provides shared invariance test implementation. Invariance 57 * rule test need only to implement the abstract methods. 58 **/ 59 class TessellationShaderInvarianceBaseTest : public TestCaseBase 60 { 61 public: 62 /* Public methods */ 63 TessellationShaderInvarianceBaseTest(Context& context, const ExtParameters& extParams, const char* name, 64 const char* description); 65 ~TessellationShaderInvarianceBaseTest(void)66 virtual ~TessellationShaderInvarianceBaseTest(void) 67 { 68 } 69 70 virtual void deinit(void); 71 virtual IterateResult iterate(void); 72 73 protected: 74 /* Protected variables */ 75 TessellationShaderUtils* m_utils_ptr; 76 77 virtual void executeDrawCall(unsigned int n_iteration); 78 virtual unsigned int getAmountOfIterations() = 0; 79 virtual unsigned int getDrawCallCountArgument(); 80 virtual std::string getFSCode(unsigned int n_iteration); 81 virtual const char* getInnerTessLevelUniformName(); 82 virtual const char* getOuterTessLevelUniformName(); 83 84 virtual void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, 85 float* out_outer_tess_levels, bool* out_point_mode, 86 _tessellation_primitive_mode* out_primitive_mode, 87 _tessellation_shader_vertex_ordering* out_vertex_ordering, 88 unsigned int* out_result_buffer_size) = 0; 89 90 virtual std::string getTCCode(unsigned int n_iteration); 91 virtual std::string getTECode(unsigned int n_iteration) = 0; 92 virtual std::string getVSCode(unsigned int n_iteration); 93 94 virtual void getXFBProperties(unsigned int n_iteration, unsigned int* out_n_names, const char*** out_names); 95 96 virtual void verifyResultDataForIteration(unsigned int n_iteration, const void* data); 97 98 virtual void verifyResultData(const void** all_iterations_data); 99 100 private: 101 /* Private type definitions */ 102 103 /* Private methods */ 104 void initTest(); 105 106 /* Private variables */ 107 typedef struct _test_program 108 { 109 glw::GLuint po_id; 110 111 glw::GLuint inner_tess_level_uniform_location; 112 glw::GLuint outer_tess_level_uniform_location; 113 114 } _test_program; 115 116 /* Defines a vector of program objects. Index corresponds to iteration index */ 117 typedef std::vector<_test_program> _programs; 118 typedef _programs::const_iterator _programs_const_iterator; 119 typedef _programs::iterator _programs_iterator; 120 121 glw::GLuint m_bo_id; 122 _programs m_programs; 123 glw::GLuint m_qo_tfpw_id; 124 glw::GLuint m_vao_id; 125 }; 126 127 /** Implementation of Test Case 42 128 * 129 * Make sure that invariance rule 1 is adhered to. Using a program object 130 * consisting of a fragment/tessellation control/tessellation evaluation/ 131 * vertex shaders, render three points/lines/triangles (A, B, C) and 132 * store vertices output by the tessellation evaluation shader. Then render 133 * the geometry in (B, C, A) order, using the same program object. Test 134 * passes if vertices stored in two different iterations for the same 135 * triangle are identical. Owing to rule 8, assume zero epsilon. 136 **/ 137 class TessellationShaderInvarianceRule1Test : public TessellationShaderInvarianceBaseTest 138 { 139 public: 140 /* Public methods */ 141 TessellationShaderInvarianceRule1Test(Context& context, const ExtParameters& extParams); 142 virtual ~TessellationShaderInvarianceRule1Test(); 143 144 protected: 145 /* Protected methods */ 146 unsigned int getAmountOfIterations(); 147 unsigned int getDrawCallCountArgument(); 148 149 void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, 150 bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, 151 _tessellation_shader_vertex_ordering* out_vertex_ordering, 152 unsigned int* out_result_buffer_size); 153 154 std::string getTECode(unsigned int n_iteration); 155 void verifyResultData(const void** all_iterations_data); 156 }; 157 158 /** Implementation of Test Case 43 159 * 160 * Make sure that invariance rule 2 is adhered to. Using a program object 161 * consisting of a fragment/tessellation control/tessellation evaluation/ 162 * vertex shaders, render a number of full-screen triangles/quads, each 163 * instance rendered with different inner tessellation level but identical 164 * outer tessellation level and spacing input layout qualifiers. Test passes 165 * if outer edge's vertices are the same for both types of geometry 166 * (each type considered separately). 167 **/ 168 class TessellationShaderInvarianceRule2Test : public TessellationShaderInvarianceBaseTest 169 { 170 public: 171 /* Public methods */ 172 TessellationShaderInvarianceRule2Test(Context& context, const ExtParameters& extParams); 173 virtual ~TessellationShaderInvarianceRule2Test(); 174 175 protected: 176 /* Protected methods */ 177 unsigned int getAmountOfIterations(); 178 179 void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, 180 bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, 181 _tessellation_shader_vertex_ordering* out_vertex_ordering, 182 unsigned int* out_result_buffer_size); 183 184 std::string getTECode(unsigned int n_iteration); 185 void verifyResultData(const void** all_iterations_data); 186 187 private: 188 /* Private variables */ 189 unsigned int m_n_tessellated_vertices[4 /* iterations in total */]; 190 }; 191 192 /** Implementation of Test Case 44 193 * 194 * Make sure that invariance rule 3 is adhered to. Using a program object 195 * consisting of a fragment/tessellation control/tessellation evaluation/ 196 * vertex shaders, tessellate a number of triangles/quads/isolines geometry 197 * with different inner/outer/vertex spacing input layout qualifiers. 198 * Capture vertices generated by tessellation evaluation stage and make sure 199 * that generated vertices are symmetrical. Owing to rule 8, assume zero 200 * epsilon. 201 **/ 202 class TessellationShaderInvarianceRule3Test : public TessellationShaderInvarianceBaseTest 203 { 204 public: 205 /* Public methods */ 206 TessellationShaderInvarianceRule3Test(Context& context, const ExtParameters& extParams); 207 virtual ~TessellationShaderInvarianceRule3Test(); 208 209 protected: 210 /* Protected methods */ 211 unsigned int getAmountOfIterations(); 212 213 void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, 214 bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, 215 _tessellation_shader_vertex_ordering* out_vertex_ordering, 216 unsigned int* out_result_buffer_size); 217 218 std::string getTECode(unsigned int n_iteration); 219 220 void verifyResultDataForIteration(unsigned int n_iteration, const void* data); 221 222 private: 223 /* Private type definitions */ 224 typedef struct _test_iteration 225 { 226 glw::GLfloat inner_tess_levels[2]; 227 glw::GLfloat outer_tess_levels[4]; 228 _tessellation_primitive_mode primitive_mode; 229 _tessellation_shader_vertex_spacing vertex_spacing; 230 231 unsigned int n_vertices; 232 _test_iterationglcts::TessellationShaderInvarianceRule3Test::_test_iteration233 _test_iteration() 234 { 235 memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); 236 memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); 237 238 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 239 vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; 240 241 n_vertices = 0; 242 } 243 } _test_iteration; 244 245 typedef std::vector<_test_iteration> _test_iterations; 246 typedef _test_iterations::const_iterator _test_iterations_const_iterator; 247 248 /* Private methods */ 249 void deinitTestIterations(); 250 void initTestIterations(); 251 252 /* Private fields */ 253 _test_iterations m_test_iterations; 254 }; 255 256 /** Implementation of Test Case 45 257 * 258 * Make sure that invariance rule 4 is adhered to. Using a program object 259 * consisting of a fragment/tessellation control/tessellation evaluation/ 260 * vertex shaders, tessellate a number of triangular and quad geometry with 261 * different inner tessellation level input layout qualifiers. 262 * Capture vertices generated by tessellation evaluation stage and make sure 263 * that all sets of vertices generated when subdividing outer edges are 264 * independent of the specific edge subdivided. 265 * 266 * Technical details: 267 * 268 * 1. The test should use a number of different inner+outer 269 * tessellation levels+vertex spacing mode configuration 270 * combinations, each resulting in a different vertex set for 271 * the generator primitive type considered. 272 * In first iteration, it should draw a screen quad, and 273 * in the other a triangle should be rendered. 274 * 2. The test should capture vertices output in TE stage. The 275 * rasterizer discard mode can be enabled, as the test is not 276 * expected to analyse visual output. 277 * 3. For quad tessellation, the test should identify vertices 278 * generated for top outer edge and make sure that remaining 279 * outer edges of the quad are built of vertices that conform 280 * to the rule. 281 * 4. For triangular tessellation, the test should identify vertices 282 * generated for one of the outer edges and then check if the other 283 * two outer edges have been generated in conformance to the rule. 284 **/ 285 class TessellationShaderInvarianceRule4Test : public TessellationShaderInvarianceBaseTest 286 { 287 public: 288 /* Public methods */ 289 TessellationShaderInvarianceRule4Test(Context& context, const ExtParameters& extParams); 290 virtual ~TessellationShaderInvarianceRule4Test(); 291 292 protected: 293 /* Protected methods */ 294 unsigned int getAmountOfIterations(); 295 296 void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, 297 bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, 298 _tessellation_shader_vertex_ordering* out_vertex_ordering, 299 unsigned int* out_result_buffer_size); 300 301 std::string getTECode(unsigned int n_iteration); 302 303 void verifyResultDataForIteration(unsigned int n_iteration, const void* data); 304 305 private: 306 /* Private type definitions */ 307 typedef struct _test_iteration 308 { 309 glw::GLfloat inner_tess_levels[2]; 310 glw::GLfloat outer_tess_levels[4]; 311 _tessellation_primitive_mode primitive_mode; 312 _tessellation_shader_vertex_spacing vertex_spacing; 313 314 unsigned int n_vertices; 315 _test_iterationglcts::TessellationShaderInvarianceRule4Test::_test_iteration316 _test_iteration() 317 { 318 memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); 319 memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); 320 321 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 322 vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; 323 324 n_vertices = 0; 325 } 326 } _test_iteration; 327 328 typedef std::vector<_test_iteration> _test_iterations; 329 typedef _test_iterations::const_iterator _test_iterations_const_iterator; 330 331 /* Private methods */ 332 void deinitTestIterations(); 333 void initTestIterations(); 334 335 bool isVertexDefined(const float* vertex_data, unsigned int n_vertices, const float* vertex_data_seeked, 336 unsigned int n_vertex_data_seeked_components); 337 338 /* Private fields */ 339 _test_iterations m_test_iterations; 340 }; 341 342 /** Implementation of Test Case 46 343 * 344 * Make sure that Rule 5 is adhered to. Using a program object 345 * consisting of a fragment/tessellation control/tessellation evaluation/ 346 * vertex shaders, tessellate a number of triangles/quads/isolines 347 * geometry with different vertex ordering input layout qualifiers. Capture 348 * vertices generated by tessellation evaluation stage and make sure that each 349 * iteration defines exactly the same set of vertices, although in different 350 * order. 351 * 352 **/ 353 class TessellationShaderInvarianceRule5Test : public TessellationShaderInvarianceBaseTest 354 { 355 public: 356 /* Public methods */ 357 TessellationShaderInvarianceRule5Test(Context& context, const ExtParameters& extParams); 358 virtual ~TessellationShaderInvarianceRule5Test(); 359 360 protected: 361 /* Protected methods */ 362 unsigned int getAmountOfIterations(); 363 364 void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, 365 bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, 366 _tessellation_shader_vertex_ordering* out_vertex_ordering, 367 unsigned int* out_result_buffer_size); 368 369 std::string getTECode(unsigned int n_iteration); 370 void verifyResultData(const void** all_iterations_data); 371 372 private: 373 /* Private type definitions */ 374 typedef struct _test_iteration 375 { 376 glw::GLfloat inner_tess_levels[2]; 377 glw::GLfloat outer_tess_levels[4]; 378 _tessellation_primitive_mode primitive_mode; 379 _tessellation_shader_vertex_ordering vertex_ordering; 380 381 unsigned int n_vertices; 382 _test_iterationglcts::TessellationShaderInvarianceRule5Test::_test_iteration383 _test_iteration() 384 { 385 memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); 386 memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); 387 388 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 389 vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN; 390 391 n_vertices = 0; 392 } 393 } _test_iteration; 394 395 typedef std::vector<_test_iteration> _test_iterations; 396 typedef _test_iterations::const_iterator _test_iterations_const_iterator; 397 398 /* Private methods */ 399 void deinitTestIterations(); 400 _test_iteration& getTestForIteration(unsigned int n_iteration); 401 void initTestIterations(); 402 bool isVertexDefined(const float* vertex_data, unsigned int n_vertices, const float* vertex_data_seeked, 403 unsigned int n_vertex_data_seeked_components); 404 405 /* Private fields */ 406 _test_iterations m_test_triangles_iterations; 407 _test_iterations m_test_quads_iterations; 408 }; 409 410 /** Implementation of Test Case 47 411 * 412 * Make sure that invariance rule 6 is adhered to. Using a program object 413 * consisting of a fragment/tessellation control/tessellation evaluation/ 414 * vertex shaders, tessellate a number of triangles/quads geometry 415 * with different inner tessellation levels/vertex spacing input layout qualifiers. 416 * Capture vertices generated by tessellation evaluation stage and make sure 417 * that all interior triangles generated during tessellation are identical 418 * except for vertex and triangle order. 419 **/ 420 class TessellationShaderInvarianceRule6Test : public TessellationShaderInvarianceBaseTest 421 { 422 public: 423 /* Public methods */ 424 TessellationShaderInvarianceRule6Test(Context& context, const ExtParameters& extParams); 425 virtual ~TessellationShaderInvarianceRule6Test(); 426 427 protected: 428 /* Protected methods */ 429 unsigned int getAmountOfIterations(); 430 431 void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, 432 bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, 433 _tessellation_shader_vertex_ordering* out_vertex_ordering, 434 unsigned int* out_result_buffer_size); 435 436 std::string getTECode(unsigned int n_iteration); 437 void verifyResultData(const void** all_iterations_data); 438 439 private: 440 /* Private type definitions */ 441 typedef struct _test_iteration 442 { 443 glw::GLfloat inner_tess_levels[2]; 444 glw::GLfloat outer_tess_levels[4]; 445 _tessellation_primitive_mode primitive_mode; 446 _tessellation_shader_vertex_ordering vertex_ordering; 447 448 unsigned int n_vertices; 449 _test_iterationglcts::TessellationShaderInvarianceRule6Test::_test_iteration450 _test_iteration() 451 { 452 memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); 453 memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); 454 455 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 456 vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN; 457 458 n_vertices = 0; 459 } 460 } _test_iteration; 461 462 typedef std::vector<_test_iteration> _test_iterations; 463 typedef _test_iterations::const_iterator _test_iterations_const_iterator; 464 465 /* Private methods */ 466 void deinitTestIterations(); 467 _test_iteration& getTestForIteration(unsigned int n_iteration); 468 void initTestIterations(); 469 470 /* Private fields */ 471 _test_iterations m_test_triangles_iterations; 472 _test_iterations m_test_quads_iterations; 473 }; 474 475 /** Implementation of Test Case 48 476 * 477 * Make sure that invariance rule 7 is adhered to. Using a program object 478 * consisting of a fragment/tessellation control/tessellation evaluation/ 479 * vertex shaders, tessellate a number of triangles/quads geometry 480 * with different vertex spacing input layout qualifiers. For each such 481 * case, the test should verify that modification of a single outer tessellation 482 * level only affects tessellation coordinates generated for a corresponding 483 * edge. Verification should be carried out by capturing vertices generated for 484 * tessellation evaluation stage and making sure that each iteration defines 485 * exactly the same set of triangles connecting inner and outer edge of the 486 * tessellated geometry for all but the modified edge. 487 **/ 488 class TessellationShaderInvarianceRule7Test : public TessellationShaderInvarianceBaseTest 489 { 490 public: 491 /* Public methods */ 492 TessellationShaderInvarianceRule7Test(Context& context, const ExtParameters& extParams); 493 virtual ~TessellationShaderInvarianceRule7Test(); 494 495 protected: 496 /* Protected methods */ 497 unsigned int getAmountOfIterations(); 498 499 void getIterationProperties(unsigned int n_iteration, float* out_inner_tess_levels, float* out_outer_tess_levels, 500 bool* out_point_mode, _tessellation_primitive_mode* out_primitive_mode, 501 _tessellation_shader_vertex_ordering* out_vertex_ordering, 502 unsigned int* out_result_buffer_size); 503 504 std::string getTECode(unsigned int n_iteration); 505 void verifyResultData(const void** all_iterations_data); 506 507 private: 508 /* Private type definitions */ 509 typedef struct _test_iteration 510 { 511 glw::GLfloat inner_tess_levels[2]; 512 glw::GLfloat outer_tess_levels[4]; 513 _tessellation_primitive_mode primitive_mode; 514 _tessellation_shader_vertex_ordering vertex_ordering; 515 516 bool is_base_iteration; 517 unsigned int n_modified_outer_tess_level; 518 unsigned int n_vertices; 519 _test_iterationglcts::TessellationShaderInvarianceRule7Test::_test_iteration520 _test_iteration() 521 { 522 memset(inner_tess_levels, 0, sizeof(inner_tess_levels)); 523 memset(outer_tess_levels, 0, sizeof(outer_tess_levels)); 524 525 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 526 vertex_ordering = TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN; 527 528 is_base_iteration = false; 529 n_modified_outer_tess_level = 0; 530 n_vertices = 0; 531 } 532 } _test_iteration; 533 534 typedef std::vector<_test_iteration> _test_iterations; 535 typedef _test_iterations::const_iterator _test_iterations_const_iterator; 536 537 /* Private methods */ 538 void deinitTestIterations(); 539 540 unsigned int getTestIterationIndex(bool is_triangles_iteration, const float* inner_tess_levels, 541 const float* outer_tess_levels, 542 _tessellation_shader_vertex_ordering vertex_ordering, 543 unsigned int n_modified_outer_tess_level); 544 545 _test_iteration& getTestForIteration(unsigned int n_iteration); 546 void initTestIterations(); 547 548 bool isTriangleDefinedInVertexDataSet(const float* base_triangle_data, const float* vertex_data, 549 unsigned int vertex_data_n_vertices); 550 551 bool isVertexDefined(const float* vertex_data, unsigned int n_vertices, const float* vertex_data_seeked, 552 unsigned int n_vertex_data_seeked_components); 553 554 /* Private fields */ 555 _test_iterations m_test_triangles_iterations; 556 _test_iterations m_test_quads_iterations; 557 }; 558 559 } // namespace glcts 560 561 #endif // _ESEXTCTESSELLATIONSHADERINVARIANCE_HPP 562