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