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 { 186 /********* General modes: do not use these values in conjugation *********/ 187 188 /* All combinations of values from the set {-1, 1, GL_MAX_TESS_GEN_LEVEL_EXT / 2, 189 * GL_MAX_TESS_GEN_LEVEL_EXT} will be used for inner/outer tesselelation 190 * levels relevant to user-specified primitive mode. 191 * An important exception is that the negative value will be SKIPPED for 192 * outer tessellation levels (because otherwise no geometry will be generated 193 * by the tessellator) 194 **/ 195 TESSELLATION_LEVEL_SET_FILTER_ALL_COMBINATIONS = 0x1, 196 197 /* Only combinations where: 198 * 199 * - inner tessellation levels use different values (inner[0] != inner[1]) 200 * - outer tessellation levels use different values (outer[0] != outer[1] != 201 * != outer[2] != outer[3]); 202 * 203 * are allowed. */ 204 TESSELLATION_LEVEL_SET_FILTER_INNER_AND_OUTER_LEVELS_USE_DIFFERENT_VALUES = 0x2, 205 206 /* All inner/outer tessellation level use the same base value */ 207 TESSELLATION_LEVEL_SET_FILTER_ALL_LEVELS_USE_THE_SAME_VALUE = 0x4, 208 209 /********* Flags: can be combined with above general mode values *********/ 210 TESSELLATION_LEVEL_SET_FILTER_EXCLUDE_NEGATIVE_BASE_VALUE = 0x8 211 } _tessellation_level_set_filter; 212 213 /* Represents primitive modes supported by GL_EXT_tessellation_shader */ 214 typedef enum 215 { 216 TESSELLATION_SHADER_PRIMITIVE_MODE_FIRST = 0, 217 218 TESSELLATION_SHADER_PRIMITIVE_MODE_ISOLINES = TESSELLATION_SHADER_PRIMITIVE_MODE_FIRST, 219 TESSELLATION_SHADER_PRIMITIVE_MODE_TRIANGLES, 220 TESSELLATION_SHADER_PRIMITIVE_MODE_QUADS, 221 222 TESSELLATION_SHADER_PRIMITIVE_MODE_COUNT, 223 TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN = TESSELLATION_SHADER_PRIMITIVE_MODE_COUNT 224 } _tessellation_primitive_mode; 225 226 /** Represents vertex ordering modes supported by GL_EXT_tessellation_shader */ 227 typedef enum 228 { 229 TESSELLATION_SHADER_VERTEX_ORDERING_CCW, 230 TESSELLATION_SHADER_VERTEX_ORDERING_CW, 231 TESSELLATION_SHADER_VERTEX_ORDERING_DEFAULT, 232 TESSELLATION_SHADER_VERTEX_ORDERING_UNKNOWN 233 } _tessellation_shader_vertex_ordering; 234 235 /** Represents vertex spacing modes supported by GL_EXT_tessellation_shader */ 236 typedef enum 237 { 238 TESSELLATION_SHADER_VERTEX_SPACING_FIRST, 239 240 TESSELLATION_SHADER_VERTEX_SPACING_EQUAL = TESSELLATION_SHADER_VERTEX_SPACING_FIRST, 241 TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_EVEN, 242 TESSELLATION_SHADER_VERTEX_SPACING_FRACTIONAL_ODD, 243 TESSELLATION_SHADER_VERTEX_SPACING_DEFAULT, 244 245 TESSELLATION_SHADER_VERTEX_SPACING_COUNT, 246 TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN = TESSELLATION_SHADER_VERTEX_SPACING_COUNT 247 } _tessellation_shader_vertex_spacing; 248 249 /** Defines what tesellation stages should be tested for a given test pass. */ 250 typedef enum 251 { 252 TESSELLATION_TEST_TYPE_FIRST, 253 254 TESSELLATION_TEST_TYPE_TCS_TES = TESSELLATION_TEST_TYPE_FIRST, /* tcs + tes stages defined */ 255 TESSELLATION_TEST_TYPE_TES, /* only tes stage defined */ 256 257 /* Always last */ 258 TESSELLATION_TEST_TYPE_COUNT, 259 TESSELLATION_TEST_TYPE_UNKNOWN = TESSELLATION_TEST_TYPE_COUNT 260 } _tessellation_test_type; 261 262 /* Stores various helper functions used across multiple tessellation shader tests */ 263 class TessellationShaderUtils 264 { 265 public: 266 /* Public methods */ 267 TessellationShaderUtils(const glw::Functions &gl, glcts::TestCaseBase *parentTest); 268 ~TessellationShaderUtils(); 269 270 void compileShaders(glw::GLint n_shaders, const glw::GLuint *shaders, bool should_succeed); 271 272 static void convertBarycentricCoordinatesToCartesian(const float *barycentric_coordinates, 273 float *out_cartesian_coordinates); 274 275 static void convertCartesianCoordinatesToBarycentric(const float *cartesian_coordinates, 276 float *out_barycentric_coordinates); 277 278 unsigned int getAmountOfVerticesGeneratedByTessellator(_tessellation_primitive_mode primitive_mode, 279 const float *inner_tessellation_level, 280 const float *outer_tessellation_level, 281 _tessellation_shader_vertex_spacing vertex_spacing, 282 bool is_point_mode_enabled); 283 284 std::vector<char> getDataGeneratedByTessellator(const float *inner, bool point_mode, 285 _tessellation_primitive_mode primitive_mode, 286 _tessellation_shader_vertex_ordering vertex_ordering, 287 _tessellation_shader_vertex_spacing vertex_spacing, 288 const float *outer); 289 290 static std::string getESTokenForPrimitiveMode(_tessellation_primitive_mode primitive_mode); 291 static std::string getESTokenForVertexOrderingMode(_tessellation_shader_vertex_ordering vertex_ordering); 292 static std::string getESTokenForVertexSpacingMode(_tessellation_shader_vertex_spacing vertex_spacing); 293 294 static std::string getGenericTCCode(unsigned int n_patch_vertices, bool should_use_glInvocationID_indexed_input); 295 296 static std::string getGenericTECode(_tessellation_shader_vertex_spacing vertex_spacing, 297 _tessellation_primitive_mode primitive_mode, 298 _tessellation_shader_vertex_ordering vertex_ordering, bool point_mode); 299 300 static glw::GLint getPatchVerticesForPrimitiveMode(_tessellation_primitive_mode primitive_mode); 301 302 static void getTessellationLevelAfterVertexSpacing(_tessellation_shader_vertex_spacing vertex_spacing, float level, 303 glw::GLint gl_max_tess_gen_level_value, float *out_clamped, 304 float *out_clamped_and_rounded); 305 306 static _tessellation_levels_set getTessellationLevelSetForPrimitiveMode(_tessellation_primitive_mode primitive_mode, 307 glw::GLint gl_max_tess_gen_level_value, 308 _tessellation_level_set_filter filter); 309 310 static glw::GLenum getTFModeForPrimitiveMode(_tessellation_primitive_mode primitive_mode, bool is_point_mode); 311 312 static bool isOuterEdgeVertex(_tessellation_primitive_mode primitive_mode, const float *tessellated_vertex_data); 313 314 static bool isTriangleDefined(const float *triangle_vertex_data, const float *vertex_data); 315 316 private: 317 /* Private type definitions */ 318 /** Defines a single counter program */ 319 typedef struct _tessellation_vertex_counter_program 320 { 321 /* Properties */ 322 float inner_tess_level[2]; 323 bool is_point_mode_enabled; 324 glw::GLint n_patch_vertices; 325 float outer_tess_level[4]; 326 _tessellation_primitive_mode primitive_mode; 327 _tessellation_shader_vertex_spacing vertex_spacing; 328 329 std::vector<char> m_data; 330 unsigned int n_data_vertices; 331 332 glw::GLint po_id; 333 glw::GLint tc_id; 334 glw::GLint te_id; 335 glw::GLint tess_level_inner_uniform_location; 336 glw::GLint tess_level_outer_uniform_location; 337 const glw::Functions &m_gl; 338 _tessellation_vertex_counter_programglcts::TessellationShaderUtils::_tessellation_vertex_counter_program339 _tessellation_vertex_counter_program(const glw::Functions &gl) : m_gl(gl) 340 { 341 memset(inner_tess_level, 0, sizeof(inner_tess_level)); 342 memset(outer_tess_level, 0, sizeof(outer_tess_level)); 343 344 is_point_mode_enabled = false; 345 n_patch_vertices = 0; 346 po_id = 0; 347 primitive_mode = TESSELLATION_SHADER_PRIMITIVE_MODE_UNKNOWN; 348 tc_id = 0; 349 te_id = 0; 350 vertex_spacing = TESSELLATION_SHADER_VERTEX_SPACING_UNKNOWN; 351 n_data_vertices = 0; 352 353 tess_level_inner_uniform_location = -1; 354 tess_level_outer_uniform_location = -1; 355 } 356 ~_tessellation_vertex_counter_programglcts::TessellationShaderUtils::_tessellation_vertex_counter_program357 ~_tessellation_vertex_counter_program() 358 { 359 if (po_id != 0) 360 { 361 m_gl.deleteProgram(po_id); 362 po_id = 0; 363 } 364 365 if (tc_id != 0) 366 { 367 m_gl.deleteShader(tc_id); 368 tc_id = 0; 369 } 370 371 if (te_id != 0) 372 { 373 m_gl.deleteShader(te_id); 374 te_id = 0; 375 } 376 } 377 } _tessellation_vertex_counter_program; 378 379 /* A vector of counter programs */ 380 typedef std::vector<_tessellation_vertex_counter_program> _programs; 381 typedef _programs::const_iterator _programs_const_iterator; 382 typedef _programs::iterator _programs_iterator; 383 384 /* Private methods */ 385 void captureTessellationData(_tessellation_vertex_counter_program &program); 386 void deinit(); 387 void init(); 388 389 void initTessellationVertexCounterProgram(const float *inner_tess_level, const float *outer_tess_level, 390 glw::GLint n_patch_vertices, 391 _tessellation_shader_vertex_spacing vertex_spacing, 392 _tessellation_primitive_mode primitive_mode, bool is_point_mode_enabled, 393 _tessellation_vertex_counter_program &result_descriptor); 394 395 /* Private variables */ 396 const glw::Functions &m_gl; 397 glw::GLuint m_bo_id; 398 glw::GLuint m_fs_id; 399 glw::GLuint m_qo_pg_id; 400 glw::GLuint m_vs_id; 401 402 glcts::TestCaseBase *m_parent_test; 403 }; 404 405 } // namespace glcts 406 407 #endif // _ESEXTCTESSELLATIONSHADERUTILS_HPP 408