1 #ifndef _ESEXTCTESSELLATIONSHADERTESSELLATION_HPP 2 #define _ESEXTCTESSELLATIONSHADERTESSELLATION_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 /** A DEQP CTS test group that collects all tests that verify tessellation 34 * functionality for multiple primitive modes at once, as opposed to some 35 * other tests that are mode-specific. 36 */ 37 class TessellationShaderTessellationTests : public glcts::TestCaseGroupBase 38 { 39 public: 40 /* Public methods */ 41 TessellationShaderTessellationTests(glcts::Context& context, const ExtParameters& extParams); 42 43 virtual ~TessellationShaderTessellationTests(void) 44 { 45 } 46 47 void init(void); 48 49 private: 50 /* Private methods */ 51 TessellationShaderTessellationTests(const TessellationShaderTessellationTests& other); 52 TessellationShaderTessellationTests& operator=(const TessellationShaderTessellationTests& other); 53 }; 54 55 /** Implementation of Test Case 24 56 * 57 * Make sure that patches, for which relevant outer tessellation levels have 58 * been defined to zero or less, are discarded by the tessellation 59 * primitive generator. Confirm that such patches never reach tessellation 60 * evaluation shader program. 61 * Cover all three tessellation primitive generator modes (triangles, quads, 62 * isolines). 63 * Note that an assumption was made here that TE's primitive id counter 64 * works on output patches that are generated afresh from data fed by TC, 65 * meaning XFBed TE-stage gl_PrimitiveID should be a sequential set, and 66 * XFBed TC-stage gl_PrimitiveID should be missing every 4th and 6th patch 67 * vertices. 68 * This is backed by http://www.khronos.org/bugzilla/show_bug.cgi?id=754 69 * 70 * Technical details: 71 * 72 * 0. If (gl_PrimitiveID % 4) == 0, TC should set all relevant outer 73 * tessellation levels to 0. 74 * 1. If (gl_PrimitiveID % 4) == 2, TC should set all relevant outer 75 * tessellation level to -1. 76 * 2. If (gl_PrimitiveID % 4) == 1 OR (gl_PrimitiveID % 4) == 3, TC should 77 * set all relevant outer tessellation levels to 1. 78 * 3. Inner tessellation level should always be set to 1. 79 * 4. TC should also set a per-vertex output variable to gl_PrimitiveID 80 * value. 81 * 5. TC should also pass gl_PrimitiveID to TE. 82 * 6. TE should store both pieces of data using Transform Feedback for each 83 * patch vertex processed. Test passes if the data retrieved is valid. 84 * 85 * 86 **/ 87 class TessellationShaderTessellationInputPatchDiscard : public TestCaseBase 88 { 89 public: 90 /* Public methods */ 91 TessellationShaderTessellationInputPatchDiscard(Context& context, const ExtParameters& extParams); 92 93 virtual ~TessellationShaderTessellationInputPatchDiscard(void) 94 { 95 } 96 97 virtual void deinit(void); 98 void initTest(void); 99 virtual IterateResult iterate(void); 100 101 private: 102 /* Private type definitions */ 103 /** Defines a single test pass */ 104 typedef struct _run 105 { 106 glw::GLuint po_id; 107 _tessellation_primitive_mode primitive_mode; 108 glw::GLuint tc_id; 109 glw::GLuint te_id; 110 111 _run() 112 { 113 po_id = 0; 114 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 115 tc_id = 0; 116 te_id = 0; 117 } 118 } _run; 119 120 /** Defines a vector of test passes */ 121 typedef std::vector<_run> _runs; 122 typedef _runs::const_iterator _runs_const_iterator; 123 124 /* Private methods */ 125 std::string getTCCode(); 126 std::string getTECode(_tessellation_primitive_mode primitive_mode); 127 128 void deinitRun(_run& test); 129 void initRun(_run& test, _tessellation_primitive_mode primitive_mode); 130 131 /* Private variables */ 132 glw::GLuint m_bo_id; 133 glw::GLuint m_fs_id; 134 glw::GLuint m_vs_id; 135 glw::GLuint m_vao_id; 136 137 _runs m_runs; 138 TessellationShaderUtils* m_utils_ptr; 139 }; 140 141 /** Implementation for Test Case 18 142 * 143 * Make sure that tessellation control shader is fed with correct gl_InvocationID 144 * values. 145 * Make sure that tessellation control and tessellation evaluation shaders are 146 * fed with correct gl_PatchVerticesIn values. 147 * Make sure that tessellation control and tessellation evaluation shaders are 148 * fed with correct gl_PrimitiveID values. Make sure restarting a primitive 149 * topology does not restart primitive counter. 150 * 151 * Technical details: 152 * 153 * 0. The test to be executed for all three geometry types supported by 154 * the tessellator. The draw calls used should draw at least a few 155 * instances of a set of patches generating a few primitives for each type 156 * considered. Vertex arrayed and indiced draw calls should be tested. 157 * A few vertices-per-patch configurations should be considered. 158 * 159 * 1. Tessellation control shader to pass gl_InvocationID to tessellation 160 * evaluation shader for XFB, for later inspection. The values captured 161 * should run from 0 to the last invocation number for particular draw 162 * call. Whole range should be covered by exactly one appearance of each index. 163 * 164 * 2. Tessellation control shader should pass gl_PatchVerticesIn value to 165 * tessellation evaluation shader. The value passed from TC, as well as 166 * gl_PatchVerticesIn value exposed to TE should be captured for later 167 * inspection. 168 * 169 * 3. Step 2 should be repeated for gl_PrimitiveID. The test should confirm 170 * that using a primitive restart index does not reset the counter, when 171 * indiced draw calls are tested. 172 **/ 173 class TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID : public TestCaseBase 174 { 175 public: 176 /* Public methods */ 177 TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID(Context& context, 178 const ExtParameters& extParams); 179 180 virtual ~TessellationShaderTessellationgl_InvocationID_PatchVerticesIn_PrimitiveID(void) 181 { 182 } 183 184 virtual void deinit(void); 185 void initTest(void); 186 virtual IterateResult iterate(void); 187 188 private: 189 /* Private type definitions */ 190 /** Defines a single test run */ 191 typedef struct _run 192 { 193 glw::GLuint bo_indices_id; 194 unsigned int drawcall_count_multiplier; 195 bool drawcall_is_indiced; 196 glw::GLuint drawcall_n_instances; 197 glw::GLuint n_instances; 198 glw::GLint n_patch_vertices; 199 unsigned int n_restart_indices; 200 unsigned int n_result_vertices; 201 glw::GLuint po_id; 202 _tessellation_primitive_mode primitive_mode; 203 glw::GLuint tc_id; 204 glw::GLuint te_id; 205 206 _run() 207 { 208 bo_indices_id = 0; 209 drawcall_count_multiplier = 0; 210 drawcall_is_indiced = false; 211 drawcall_n_instances = 0; 212 n_result_vertices = 0; 213 n_instances = 0; 214 n_patch_vertices = 0; 215 n_restart_indices = 0; 216 po_id = 0; 217 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 218 tc_id = 0; 219 te_id = 0; 220 } 221 } _run; 222 223 /** Defines a vector of test runs */ 224 typedef std::vector<_run> _runs; 225 typedef _runs::const_iterator _runs_const_iterator; 226 227 /* Private methods */ 228 std::string getTCCode(glw::GLuint n_patch_vertices); 229 std::string getTECode(_tessellation_primitive_mode primitive_mode); 230 231 void deinitRun(_run& run); 232 233 void initRun(_run& run, _tessellation_primitive_mode primitive_mode, glw::GLint n_patch_vertices, bool is_indiced, 234 glw::GLint n_instances, unsigned int drawcall_count_multiplier); 235 236 /* Private variables */ 237 glw::GLuint m_bo_id; 238 glw::GLuint m_fs_id; 239 glw::GLuint m_vs_id; 240 glw::GLuint m_vao_id; 241 242 _runs m_runs; 243 TessellationShaderUtils* m_utils_ptr; 244 }; 245 246 /** Implementation of Test Case 51 247 * 248 * Make sure that coordinates of all triangles generated by fixed-function 249 * tessellation primitive generator meet the barycentric coordinate requirement 250 * u + v + w = 1 251 * 252 * Consider a few inner/outer tessellation level combinations 253 * for triangle and quad inputs of a tessellation evaluation shader. 254 * 255 * Epsilon: 1e-5. This is dictated by the language in ES 3.0 specification, 256 * which seems to be the best pick, given that the tessellator is 257 * a fixed-function unit. 258 * 259 * Make sure that gl_TessCoord is not an array. 260 * Make sure that gl_TessCoord is not accessible for any of the vertices in 261 * gl_in[]. 262 * Make sure that (u, v, w) coordinates are in range [0, 1] for all 263 * tessellation primitive modes. 264 * Make sure that the w coordinate is always zero for "quads" and "isolines" 265 * tessellation primitive modes. 266 * 267 * This test should be executed in two invocations, depending on the test type: 268 * 269 * * Without a tessellation control shader, where the patch tessellation levels 270 * are configured by using glPatchParameterfv() function (*); 271 * * With a tessellation control shader used to configure the levels; 272 * 273 * (*) Only applies to Desktop 274 * 275 **/ 276 class TessellationShaderTessellationgl_TessCoord : public TestCaseBase 277 { 278 static std::string getTypeName(_tessellation_test_type test_type); 279 280 public: 281 /* Public methods */ 282 TessellationShaderTessellationgl_TessCoord(Context& context, const ExtParameters& extParams, 283 _tessellation_test_type test_type); 284 285 virtual ~TessellationShaderTessellationgl_TessCoord(void) 286 { 287 } 288 289 virtual void deinit(void); 290 void initTest(void); 291 virtual IterateResult iterate(void); 292 293 private: 294 /* Private type definitions */ 295 /** Defines a single test pass */ 296 typedef struct _test_descriptor 297 { 298 glw::GLint n_patch_vertices; 299 glw::GLuint po_id; 300 _tessellation_primitive_mode primitive_mode; 301 glw::GLuint tc_id; 302 glw::GLuint te_id; 303 glw::GLfloat tess_level_inner[2]; 304 glw::GLfloat tess_level_outer[4]; 305 _tessellation_test_type type; 306 _tessellation_shader_vertex_spacing vertex_spacing; 307 308 glw::GLint inner_tess_level_uniform_location; 309 glw::GLint outer_tess_level_uniform_location; 310 311 _test_descriptor() 312 { 313 memset(tess_level_inner, 0, sizeof(tess_level_inner)); 314 memset(tess_level_outer, 0, sizeof(tess_level_outer)); 315 316 n_patch_vertices = 0; 317 po_id = 0; 318 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 319 tc_id = 0; 320 te_id = 0; 321 type = TESSELLATION_TEST_TYPE_UNKNOWN; 322 vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; 323 324 inner_tess_level_uniform_location = -1; 325 outer_tess_level_uniform_location = -1; 326 } 327 } _test_descriptor; 328 329 /** Defines a vector of test passes */ 330 typedef std::vector<_test_descriptor> _tests; 331 typedef _tests::const_iterator _tests_const_iterator; 332 333 /* Private methods */ 334 std::string getTCCode(glw::GLint n_patch_vertices); 335 336 std::string getTECode(_tessellation_shader_vertex_spacing vertex_spacing, 337 _tessellation_primitive_mode primitive_mode); 338 339 void deinitTestDescriptor(_test_descriptor& test); 340 341 void initTestDescriptor(_test_descriptor& test, _tessellation_shader_vertex_spacing vertex_spacing, 342 _tessellation_primitive_mode primitive_mode, glw::GLint n_patch_vertices, 343 const float* inner_tess_levels, const float* outer_tess_levels, 344 _tessellation_test_type test_type); 345 346 /* Private variables */ 347 _tessellation_test_type m_test_type; 348 glw::GLuint m_bo_id; 349 glw::GLuint m_broken_ts_id; 350 glw::GLuint m_fs_id; 351 glw::GLuint m_vs_id; 352 glw::GLuint m_vao_id; 353 354 _tests m_tests; 355 TessellationShaderUtils* m_utils_ptr; 356 }; 357 358 /* This test class implements the following test cases: 359 * 360 * 20. Make sure it is possible to use up to GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT/4 361 * vec4 input variables in a tessellation control shader. 362 * Make sure it is possible to use up to GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT/4 363 * vec4 input variables in a tessellation evaluation shader. 364 * This test should issue at least one draw call and verify the results to 365 * make sure the implementation actually supports the maximums it reports. 366 * 367 * 21. Make sure it is possible to use up to GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT/4 368 * vec4 per-vertex output variables in a tessellation control shader. 369 * Make sure it is possible to use up to GL_MAX_TESS_PATCH_COMPONENTS_EXT/4 370 * vec4 per-patch output variables in a tessellation control shader. 371 * Make sure it is possible to use up to GL_MAX_TESS_PATCH_COMPONENTS_EXT/4 372 * vec4 per-patch input variables in a tessellation evaluation shader. 373 * Make sure it is possible to use up to GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT/4 374 * vec4 per-vertex output variables in a tessellation evaluation shader. 375 * 376 * NOTE: The test should separately check if a maximum number of per-vertex and 377 * per-patch output variables used in a tessellation control shader works 378 * correctly. This is due to a risk that, had both types been used at once, 379 * the maximum amount of output components supported for tessellation 380 * control shader GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT may 381 * have been exceeded for implementations, for which the property is 382 * not equal to: 383 * 384 * (per-vertex output component count multiplied by output patch size + 385 * + per-patch output component count). 386 * 387 * This test should issue at least one draw call and verify the results to 388 * make sure the implementation actually supports the maximums it reports. 389 * 390 * Category: Functional Test. 391 * Priority: Must-Have 392 * 393 * The test is implemented by checking two different cases: 394 * 1) In first case, it makes sure it is possible to use up to: 395 * - GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation control shader, 396 * - GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation control shader, 397 * - GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation evaluation shader, 398 * - GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT / 4 vec4 per-vertex variables in tessellation evaluation shader. 399 * 400 * 2) In second case, it makes sure it is possible to use up to: 401 * - GL_MAX_TESS_PATCH_COMPONENTS_EXT/4 vec4 per-patch variables in tessellation control shader, 402 * - GL_MAX_TESS_PATCH_COMPONENTS_EXT/4 vec4 per-patch variables in tessellation evaluation shader. 403 */ 404 class TessellationShaderTessellationMaxInOut : public TestCaseBase 405 { 406 public: 407 /* Public methods */ 408 TessellationShaderTessellationMaxInOut(Context& context, const ExtParameters& extParams); 409 410 virtual ~TessellationShaderTessellationMaxInOut() 411 { 412 } 413 414 virtual void deinit(void); 415 virtual IterateResult iterate(void); 416 417 private: 418 /* private methods */ 419 void initBufferObjects(void); 420 void initProgramObjects(void); 421 void initReferenceValues(void); 422 void initTest(void); 423 void retrieveGLConstantValues(void); 424 425 bool compareValues(char const* description, glw::GLfloat* reference_values, int n_reference_values); 426 427 /* private variables */ 428 glw::GLuint m_po_id_1; /* program object name for case 1 */ 429 glw::GLuint m_po_id_2; /* program object name for case 2 */ 430 431 glw::GLuint m_fs_id; /* fragment shader object name */ 432 glw::GLuint m_tcs_id_1; /* tessellation control shader object name for case 1 */ 433 glw::GLuint m_tcs_id_2; /* tessellation control shader object name for case 2 */ 434 glw::GLuint m_tes_id_1; /* tessellation evaluation shader object name for case 1 */ 435 glw::GLuint m_tes_id_2; /* tessellation evaluation shader object name for case 2 */ 436 glw::GLuint m_vs_id_1; /* vertex shader object name for case 1 */ 437 glw::GLuint m_vs_id_2; /* vertex shader object name for case 2 */ 438 439 glw::GLuint m_tf_bo_id_1; /* buffer object name */ 440 glw::GLuint m_tf_bo_id_2; /* buffer object name */ 441 glw::GLuint m_patch_data_bo_id; /* buffer object name for patch submission */ 442 443 glw::GLuint m_vao_id; /* vertex array object */ 444 445 glw::GLint m_gl_max_tess_control_input_components_value; /* value of MAX_TESS_CONTROL_INPUT_COMPONENTS */ 446 glw::GLint m_gl_max_tess_control_output_components_value; /* value of MAX_TESS_CONTROL_OUTPUT_COMPONENTS */ 447 glw::GLint m_gl_max_tess_evaluation_input_components_value; /* value of MAX_TESS_EVALUATION_INPUT_COMPONENTS */ 448 glw::GLint m_gl_max_tess_evaluation_output_components_value; /* value of MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */ 449 glw::GLint 450 m_gl_max_transform_feedback_interleaved_components_value; /* value of MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS */ 451 glw::GLint m_gl_max_tess_patch_components_value; /* value of MAX_TESS_PATCH_COMPONENTS */ 452 glw::GLint m_gl_max_vertex_output_components_value; /* value of MAX_VERTEX_OUTPUT_COMPONENTS */ 453 454 glw::GLfloat m_ref_patch_attributes[4]; /* reference values for max per-patch attributes case 2 */ 455 glw::GLfloat* m_ref_vertex_attributes; /* reference values for max per-vertex attributes case 1 */ 456 457 static const char* m_fs_code; /* fragment shader code */ 458 static const char* m_vs_code; /* vertex shader code */ 459 static const char* m_tcs_code_1; /* tessellation control shader code for per vertex components check */ 460 static const char* m_tcs_code_2; /* tessellation control shader code per patch components check */ 461 static const char* m_tes_code_1; /* tessellation evaluation shader code per vertex components check */ 462 static const char* m_tes_code_2; /* tessellation evaluation shader code per patch components check */ 463 464 char** m_tf_varyings_names; /* transform feedback varyings names array */ 465 }; 466 467 } // namespace glcts 468 469 #endif // _ESEXTCTESSELLATIONSHADERTESSELLATION_HPP 470