• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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