1 #ifndef _ESEXTCTESSELLATIONSHADERUTILS_HPP 2 #define _ESEXTCTESSELLATIONSHADERUTILS_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 "gluContextInfo.hpp" 28 #include "gluDefs.hpp" 29 #include "glwFunctions.hpp" 30 #include "tcuDefs.hpp" 31 #include <cstring> 32 #include <vector> 33 34 namespace glcts 35 { 36 37 /** Stores an ivec4 representation */ 38 typedef struct _ivec4 39 { 40 int x; 41 int y; 42 int z; 43 int w; 44 45 /** Constructor. 46 * 47 * @param in_x Value to use for X component; 48 * @param in_y Value to use for Y component; 49 * @param in_z Value to use for Z component; 50 * @param in_w Value to use for W component. 51 */ _ivec4glcts::_ivec452 _ivec4(int in_x, int in_y, int in_z, int in_w) 53 { 54 x = in_x; 55 y = in_y; 56 z = in_z; 57 w = in_w; 58 } 59 60 /** Compares all components of _ivec4 instance with 61 * another instance. 62 * 63 * @return true if all components match, false otherwise. 64 **/ operator ==glcts::_ivec465 bool operator==(const _ivec4& in) const 66 { 67 return (x == in.x) && (y == in.y) && (z == in.z) && (w == in.w); 68 } 69 70 /** Implements inequality operator. 71 * 72 * @return true if any of the compared components 73 * do not match, false otherwise. 74 **/ operator !=glcts::_ivec475 bool operator!=(const _ivec4& in) const 76 { 77 return !(*this == in); 78 } 79 } _ivec4; 80 81 /* Stores a vec2 representation */ 82 typedef struct _vec2 83 { 84 float x; 85 float y; 86 87 /** Constructor. 88 * 89 * @param in_x Value to use for X component; 90 * @param in_y Value to use for Y component; 91 */ _vec2glcts::_vec292 _vec2(float in_x, float in_y) 93 { 94 x = in_x; 95 y = in_y; 96 } 97 98 /** Compares all components of _vec2 instance with 99 * another instance, using == operator. 100 * 101 * @return true if all components match, false otherwise. 102 **/ operator ==glcts::_vec2103 bool operator==(const _vec2& in) const 104 { 105 return (x == in.x) && (y == in.y); 106 } 107 108 /** Implements inequality operator. 109 * 110 * @return true if any of the compared components 111 * do not match, false otherwise. 112 **/ operator !=glcts::_vec2113 bool operator!=(const _vec2& in) const 114 { 115 return !(*this == in); 116 } 117 } _vec2; 118 119 /* Stores a vec4 representation */ 120 typedef struct _vec4 121 { 122 float x; 123 float y; 124 float z; 125 float w; 126 127 /** Constructor. 128 * 129 * @param in_x Value to use for X component; 130 * @param in_y Value to use for Y component; 131 * @param in_z Value to use for Z component; 132 * @param in_w Value to use for W component. 133 */ _vec4glcts::_vec4134 _vec4(float in_x, float in_y, float in_z, float in_w) 135 { 136 x = in_x; 137 y = in_y; 138 z = in_z; 139 w = in_w; 140 } 141 142 /** Compares all components of _vec4 instance with 143 * another instance, using == operator. 144 * 145 * @return true if all components match, false otherwise. 146 **/ operator ==glcts::_vec4147 bool operator==(const _vec4& in) const 148 { 149 return (x == in.x) && (y == in.y) && (z == in.z) && (w == in.w); 150 } 151 152 /** Implements inequality operator. 153 * 154 * @return true if any of the compared components 155 * do not match, false otherwise. 156 **/ operator !=glcts::_vec4157 bool operator!=(const _vec4& in) const 158 { 159 return !(*this == in); 160 } 161 } _vec4; 162 163 /** Defines a set of tessellation inner+outer levels */ 164 typedef struct _tessellation_levels 165 { 166 float inner[2]; 167 float outer[4]; 168 _tessellation_levelsglcts::_tessellation_levels169 _tessellation_levels() 170 { 171 memset(inner, 0, sizeof(inner)); 172 memset(outer, 0, sizeof(outer)); 173 } 174 } _tessellation_levels; 175 176 /* Defines a vector of tessellation levels */ 177 typedef std::vector<_tessellation_levels> _tessellation_levels_set; 178 typedef _tessellation_levels_set::const_iterator _tessellation_levels_set_const_iterator; 179 typedef _tessellation_levels_set::iterator _tessellation_levels_set_iterator; 180 181 /* Determines condition that returned level sets should meet in order to be returned 182 * by TessellationShaderUtils::getTessellationLevelSetForPrimitiveMode() . 183 */ 184 typedef enum { 185 /********* General modes: do not use these values in conjugation *********/ 186 187 /* All combinations of values from the set {-1, 1, GL_MAX_TESS_GEN_LEVEL_EXT / 2, 188 * GL_MAX_TESS_GEN_LEVEL_EXT} will be used for inner/outer tesselelation 189 * levels relevant to user-specified primitive mode. 190 * An important exception is that the negative value will be SKIPPED for 191 * outer tessellation levels (because otherwise no geometry will be generated 192 * by the tessellator) 193 **/ 194 TESSELLATION_LEVEL_SET_FILTER_ALL_COMBINATIONS = 0x1, 195 196 /* Only combinations where: 197 * 198 * - inner tessellation levels use different values (inner[0] != inner[1]) 199 * - outer tessellation levels use different values (outer[0] != outer[1] != 200 * != outer[2] != outer[3]); 201 * 202 * are allowed. */ 203 TESSELLATION_LEVEL_SET_FILTER_INNER_AND_OUTER_LEVELS_USE_DIFFERENT_VALUES = 0x2, 204 205 /* All inner/outer tessellation level use the same base value */ 206 TESSELLATION_LEVEL_SET_FILTER_ALL_LEVELS_USE_THE_SAME_VALUE = 0x4, 207 208 /********* Flags: can be combined with above general mode values *********/ 209 TESSELLATION_LEVEL_SET_FILTER_EXCLUDE_NEGATIVE_BASE_VALUE = 0x8 210 } _tessellation_level_set_filter; 211 212 /* Represents primitive modes supported by GL_EXT_tessellation_shader */ 213 typedef enum { 214 TESSELLATION_SHADER_PRIMITIVE_MODE_FIRST = 0, 215 216 TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES = TESSELLATION_SHADER_PRIMITIVE_MODE_FIRST, 217 TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, 218 TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS, 219 220 TESSELLATION_SHADER_PRIMITIVE_MODE_COUNT, 221 TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN = TESSELLATION_SHADER_PRIMITIVE_MODE_COUNT 222 } _tessellation_primitive_mode; 223 224 /** Represents vertex ordering modes supported by GL_EXT_tessellation_shader */ 225 typedef enum { 226 TESSELLATION_SHADER_VERTEX_ORDERING_CCW, 227 TESSELLATION_SHADER_VERTEX_ORDERING_CW, 228 TESSELLATION_SHADER_VERTEX_ORDERING_DEFAULT, 229 TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN 230 } _tessellation_shader_vertex_ordering; 231 232 /** Represents vertex spacing modes supported by GL_EXT_tessellation_shader */ 233 typedef enum { 234 TESSELLATION_SHADER_VERTEX_SPACING_FIRST, 235 236 TESSELLATION_SHADER_VERTEX_SPACING_EQUAL = TESSELLATION_SHADER_VERTEX_SPACING_FIRST, 237 TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_EVEN, 238 TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD, 239 TESSELLATION_SHADER_VERTEX_SPACING_DEFAULT, 240 241 TESSELLATION_SHADER_VERTEX_SPACING_COUNT, 242 TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN = TESSELLATION_SHADER_VERTEX_SPACING_COUNT 243 } _tessellation_shader_vertex_spacing; 244 245 /** Defines what tesellation stages should be tested for a given test pass. */ 246 typedef enum { 247 TESSELLATION_TEST_TYPE_FIRST, 248 249 TESSELLATION_TEST_TYPE_TCS_TES = TESSELLATION_TEST_TYPE_FIRST, /* tcs + tes stages defined */ 250 TESSELLATION_TEST_TYPE_TES, /* only tes stage defined */ 251 252 /* Always last */ 253 TESSELLATION_TEST_TYPE_COUNT, 254 TESSELLATION_TEST_TYPE_UNKNOWN = TESSELLATION_TEST_TYPE_COUNT 255 } _tessellation_test_type; 256 257 /* Stores various helper functions used across multiple tessellation shader tests */ 258 class TessellationShaderUtils 259 { 260 public: 261 /* Public methods */ 262 TessellationShaderUtils(const glw::Functions& gl, glcts::TestCaseBase* parentTest); 263 ~TessellationShaderUtils(); 264 265 void compileShaders(glw::GLint n_shaders, const glw::GLuint* shaders, bool should_succeed); 266 267 static void convertBarycentricCoordinatesToCartesian(const float* barycentric_coordinates, 268 float* out_cartesian_coordinates); 269 270 static void convertCartesianCoordinatesToBarycentric(const float* cartesian_coordinates, 271 float* out_barycentric_coordinates); 272 273 unsigned int getAmountOfVerticesGeneratedByTessellator(_tessellation_primitive_mode primitive_mode, 274 const float* inner_tessellation_level, 275 const float* outer_tessellation_level, 276 _tessellation_shader_vertex_spacing vertex_spacing, 277 bool is_point_mode_enabled); 278 279 std::vector<char> getDataGeneratedByTessellator(const float* inner, bool point_mode, 280 _tessellation_primitive_mode primitive_mode, 281 _tessellation_shader_vertex_ordering vertex_ordering, 282 _tessellation_shader_vertex_spacing vertex_spacing, 283 const float* outer); 284 285 static std::string getESTokenForPrimitiveMode(_tessellation_primitive_mode primitive_mode); 286 static std::string getESTokenForVertexOrderingMode(_tessellation_shader_vertex_ordering vertex_ordering); 287 static std::string getESTokenForVertexSpacingMode(_tessellation_shader_vertex_spacing vertex_spacing); 288 289 static std::string getGenericTCCode(unsigned int n_patch_vertices, bool should_use_glInvocationID_indexed_input); 290 291 static std::string getGenericTECode(_tessellation_shader_vertex_spacing vertex_spacing, 292 _tessellation_primitive_mode primitive_mode, 293 _tessellation_shader_vertex_ordering vertex_ordering, bool point_mode); 294 295 static glw::GLint getPatchVerticesForPrimitiveMode(_tessellation_primitive_mode primitive_mode); 296 297 static void getTessellationLevelAfterVertexSpacing(_tessellation_shader_vertex_spacing vertex_spacing, float level, 298 glw::GLint gl_max_tess_gen_level_value, float* out_clamped, 299 float* out_clamped_and_rounded); 300 301 static _tessellation_levels_set getTessellationLevelSetForPrimitiveMode(_tessellation_primitive_mode primitive_mode, 302 glw::GLint gl_max_tess_gen_level_value, 303 _tessellation_level_set_filter filter); 304 305 static glw::GLenum getTFModeForPrimitiveMode(_tessellation_primitive_mode primitive_mode, bool is_point_mode); 306 307 static bool isOuterEdgeVertex(_tessellation_primitive_mode primitive_mode, const float* tessellated_vertex_data); 308 309 static bool isTriangleDefined(const float* triangle_vertex_data, const float* vertex_data); 310 311 private: 312 /* Private type definitions */ 313 /** Defines a single counter program */ 314 typedef struct _tessellation_vertex_counter_program 315 { 316 /* Properties */ 317 float inner_tess_level[2]; 318 bool is_point_mode_enabled; 319 glw::GLint n_patch_vertices; 320 float outer_tess_level[4]; 321 _tessellation_primitive_mode primitive_mode; 322 _tessellation_shader_vertex_spacing vertex_spacing; 323 324 std::vector<char> m_data; 325 unsigned int n_data_vertices; 326 327 glw::GLint po_id; 328 glw::GLint tc_id; 329 glw::GLint te_id; 330 glw::GLint tess_level_inner_uniform_location; 331 glw::GLint tess_level_outer_uniform_location; 332 const glw::Functions& m_gl; 333 _tessellation_vertex_counter_programglcts::TessellationShaderUtils::_tessellation_vertex_counter_program334 _tessellation_vertex_counter_program(const glw::Functions& gl) : m_gl(gl) 335 { 336 memset(inner_tess_level, 0, sizeof(inner_tess_level)); 337 memset(outer_tess_level, 0, sizeof(outer_tess_level)); 338 339 is_point_mode_enabled = false; 340 n_patch_vertices = 0; 341 po_id = 0; 342 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 343 tc_id = 0; 344 te_id = 0; 345 vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; 346 n_data_vertices = 0; 347 348 tess_level_inner_uniform_location = -1; 349 tess_level_outer_uniform_location = -1; 350 } 351 ~_tessellation_vertex_counter_programglcts::TessellationShaderUtils::_tessellation_vertex_counter_program352 ~_tessellation_vertex_counter_program() 353 { 354 if (po_id != 0) 355 { 356 m_gl.deleteProgram(po_id); 357 po_id = 0; 358 } 359 360 if (tc_id != 0) 361 { 362 m_gl.deleteShader(tc_id); 363 tc_id = 0; 364 } 365 366 if (te_id != 0) 367 { 368 m_gl.deleteShader(te_id); 369 te_id = 0; 370 } 371 } 372 } _tessellation_vertex_counter_program; 373 374 /* A vector of counter programs */ 375 typedef std::vector<_tessellation_vertex_counter_program> _programs; 376 typedef _programs::const_iterator _programs_const_iterator; 377 typedef _programs::iterator _programs_iterator; 378 379 /* Private methods */ 380 void captureTessellationData(_tessellation_vertex_counter_program& program); 381 void deinit(); 382 void init(); 383 384 void initTessellationVertexCounterProgram(const float* inner_tess_level, const float* outer_tess_level, 385 glw::GLint n_patch_vertices, 386 _tessellation_shader_vertex_spacing vertex_spacing, 387 _tessellation_primitive_mode primitive_mode, bool is_point_mode_enabled, 388 _tessellation_vertex_counter_program& result_descriptor); 389 390 /* Private variables */ 391 const glw::Functions& m_gl; 392 glw::GLuint m_bo_id; 393 glw::GLuint m_fs_id; 394 glw::GLuint m_qo_pg_id; 395 glw::GLuint m_vs_id; 396 397 glcts::TestCaseBase* m_parent_test; 398 }; 399 400 } // namespace glcts 401 402 #endif // _ESEXTCTESSELLATIONSHADERUTILS_HPP 403