1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2017 The Khronos Group Inc.
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci */ /*!
20e5c31af7Sopenharmony_ci * \file glcSeparableProgramXFBTests.cpp
21e5c31af7Sopenharmony_ci * \brief
22e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "glcSeparableProgramsTransformFeedbackTests.hpp"
25e5c31af7Sopenharmony_ci#include "glcViewportArrayTests.hpp"
26e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
27e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
28e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
29e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
30e5c31af7Sopenharmony_ci#include "tcuCommandLine.hpp"
31e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
32e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_ciusing namespace tcu;
35e5c31af7Sopenharmony_ciusing namespace glu;
36e5c31af7Sopenharmony_ciusing namespace glw;
37e5c31af7Sopenharmony_ciusing namespace glcts::ViewportArray;
38e5c31af7Sopenharmony_ci
39e5c31af7Sopenharmony_cinamespace glcts
40e5c31af7Sopenharmony_ci{
41e5c31af7Sopenharmony_ci
42e5c31af7Sopenharmony_ci/**
43e5c31af7Sopenharmony_ci * @brief The StageIndex enum. Stages order coresponds to order
44e5c31af7Sopenharmony_ci * in which shader sources are specified in Utils::program::build.
45e5c31af7Sopenharmony_ci */
46e5c31af7Sopenharmony_cienum StageIndex
47e5c31af7Sopenharmony_ci{
48e5c31af7Sopenharmony_ci	FRAGMENT_STAGE_INDEX = 0,
49e5c31af7Sopenharmony_ci	GEOMETRY_STAGE_INDEX,
50e5c31af7Sopenharmony_ci	TESSELLATION_CONTROL_STAGE,
51e5c31af7Sopenharmony_ci	TESSELLATION_EVALUATION_STAGE,
52e5c31af7Sopenharmony_ci	VERTEX_STAGE,
53e5c31af7Sopenharmony_ci	STAGES_COUNT
54e5c31af7Sopenharmony_ci};
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_ci/**
57e5c31af7Sopenharmony_ci * @brief The StageTokens array. Stages order coresponds to order
58e5c31af7Sopenharmony_ci * in which shader sources are specified in Utils::program::build.
59e5c31af7Sopenharmony_ci */
60e5c31af7Sopenharmony_cistatic const GLenum StageTokens[STAGES_COUNT] = { GL_FRAGMENT_SHADER_BIT, GL_GEOMETRY_SHADER_BIT,
61e5c31af7Sopenharmony_ci												  GL_TESS_CONTROL_SHADER_BIT, GL_TESS_EVALUATION_SHADER_BIT,
62e5c31af7Sopenharmony_ci												  GL_VERTEX_SHADER_BIT };
63e5c31af7Sopenharmony_ci
64e5c31af7Sopenharmony_ci/**
65e5c31af7Sopenharmony_ci * @brief The StageData structure.
66e5c31af7Sopenharmony_ci */
67e5c31af7Sopenharmony_cistruct StageData
68e5c31af7Sopenharmony_ci{
69e5c31af7Sopenharmony_ci	const GLchar*		 source;
70e5c31af7Sopenharmony_ci	const GLchar* const* tfVaryings;
71e5c31af7Sopenharmony_ci	const GLuint		 tfVaryingsCount;
72e5c31af7Sopenharmony_ci};
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ci/**
75e5c31af7Sopenharmony_ci * @brief The PerStageData structure containimg shader data per all stages.
76e5c31af7Sopenharmony_ci */
77e5c31af7Sopenharmony_cistruct PerStageData
78e5c31af7Sopenharmony_ci{
79e5c31af7Sopenharmony_ci	StageData stage[STAGES_COUNT];
80e5c31af7Sopenharmony_ci};
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_cistatic const GLchar* vs_code = "${VERSION}\n"
83e5c31af7Sopenharmony_ci							   "flat out highp int o_vert;\n"
84e5c31af7Sopenharmony_ci							   "${PERVERTEX_BLOCK}\n"
85e5c31af7Sopenharmony_ci							   "void main()\n"
86e5c31af7Sopenharmony_ci							   "{\n"
87e5c31af7Sopenharmony_ci							   "    o_vert = 1;\n"
88e5c31af7Sopenharmony_ci							   "    gl_Position = vec4(1, 0, 0, 1);\n"
89e5c31af7Sopenharmony_ci							   "}\n";
90e5c31af7Sopenharmony_ci
91e5c31af7Sopenharmony_cistatic const GLchar* vs_tf_varyings[] = { "o_vert" };
92e5c31af7Sopenharmony_ci
93e5c31af7Sopenharmony_cistatic const GLchar* tcs_code = "${VERSION}\n"
94e5c31af7Sopenharmony_ci								"layout(vertices = 1) out;\n"
95e5c31af7Sopenharmony_ci								"flat in highp int o_vert[];\n"
96e5c31af7Sopenharmony_ci								"${PERVERTEX_BLOCK}\n"
97e5c31af7Sopenharmony_ci								"void main()\n"
98e5c31af7Sopenharmony_ci								"{\n"
99e5c31af7Sopenharmony_ci								"    gl_TessLevelInner[0] = 1.0;\n"
100e5c31af7Sopenharmony_ci								"    gl_TessLevelInner[1] = 1.0;\n"
101e5c31af7Sopenharmony_ci								"    gl_TessLevelOuter[0] = 1.0;\n"
102e5c31af7Sopenharmony_ci								"    gl_TessLevelOuter[1] = 1.0;\n"
103e5c31af7Sopenharmony_ci								"    gl_TessLevelOuter[2] = 1.0;\n"
104e5c31af7Sopenharmony_ci								"    gl_TessLevelOuter[3] = 1.0;\n"
105e5c31af7Sopenharmony_ci								"}\n";
106e5c31af7Sopenharmony_ci
107e5c31af7Sopenharmony_cistatic const GLchar* tes_code = "${VERSION}\n"
108e5c31af7Sopenharmony_ci								"layout (triangles, point_mode) in;\n"
109e5c31af7Sopenharmony_ci								"flat out highp int o_tess;\n"
110e5c31af7Sopenharmony_ci								"${PERVERTEX_BLOCK}\n"
111e5c31af7Sopenharmony_ci								"void main()\n"
112e5c31af7Sopenharmony_ci								"{\n"
113e5c31af7Sopenharmony_ci								"    o_tess = 2;\n"
114e5c31af7Sopenharmony_ci								"    gl_Position = vec4(gl_TessCoord.xy*2.0 - 1.0, 0.0, 1.0);\n"
115e5c31af7Sopenharmony_ci								"}\n";
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_cistatic const GLchar* tes_tf_varyings[] = { "o_tess" };
118e5c31af7Sopenharmony_ci
119e5c31af7Sopenharmony_cistatic const GLchar* gs_code = "${VERSION}\n"
120e5c31af7Sopenharmony_ci							   "layout (points) in;\n"
121e5c31af7Sopenharmony_ci							   "layout (points, max_vertices = 3) out;\n"
122e5c31af7Sopenharmony_ci							   "${PERVERTEX_BLOCK}\n"
123e5c31af7Sopenharmony_ci							   "flat in highp int ${IN_VARYING_NAME}[];\n"
124e5c31af7Sopenharmony_ci							   "flat out highp int o_geom;\n"
125e5c31af7Sopenharmony_ci							   "void main()\n"
126e5c31af7Sopenharmony_ci							   "{\n"
127e5c31af7Sopenharmony_ci							   "    o_geom = 3;\n"
128e5c31af7Sopenharmony_ci							   "    gl_Position  = vec4(-1, -1, 0, 1);\n"
129e5c31af7Sopenharmony_ci							   "    EmitVertex();\n"
130e5c31af7Sopenharmony_ci							   "    o_geom = 3;\n"
131e5c31af7Sopenharmony_ci							   "    gl_Position  = vec4(-1, 1, 0, 1);\n"
132e5c31af7Sopenharmony_ci							   "    EmitVertex();\n"
133e5c31af7Sopenharmony_ci							   "    o_geom = 3;\n"
134e5c31af7Sopenharmony_ci							   "    gl_Position  = vec4(1, -1, 0, 1);\n"
135e5c31af7Sopenharmony_ci							   "    EmitVertex();\n"
136e5c31af7Sopenharmony_ci							   "}\n";
137e5c31af7Sopenharmony_ci
138e5c31af7Sopenharmony_cistatic const GLchar* gs_tf_varyings[] = { "o_geom" };
139e5c31af7Sopenharmony_ci
140e5c31af7Sopenharmony_cistatic const GLchar* fs_code = "${VERSION}\n"
141e5c31af7Sopenharmony_ci							   "flat in highp int ${IN_VARYING_NAME};"
142e5c31af7Sopenharmony_ci							   "out highp vec4 o_color;\n"
143e5c31af7Sopenharmony_ci							   "void main()\n"
144e5c31af7Sopenharmony_ci							   "{\n"
145e5c31af7Sopenharmony_ci							   "    o_color = vec4(1.0);\n"
146e5c31af7Sopenharmony_ci							   "}\n";
147e5c31af7Sopenharmony_ci
148e5c31af7Sopenharmony_ciclass SeparableProgramTFTestCase : public deqp::TestCase
149e5c31af7Sopenharmony_ci{
150e5c31af7Sopenharmony_cipublic:
151e5c31af7Sopenharmony_ci	/* Public methods */
152e5c31af7Sopenharmony_ci	SeparableProgramTFTestCase(deqp::Context& context, const char* name, PerStageData shaderData, GLint expectedValue);
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_ci	tcu::TestNode::IterateResult iterate(void);
155e5c31af7Sopenharmony_ci
156e5c31af7Sopenharmony_ciprotected:
157e5c31af7Sopenharmony_ci	/* Protected attributes */
158e5c31af7Sopenharmony_ci	PerStageData m_shaderData;
159e5c31af7Sopenharmony_ci	GLint		 m_expectedValue;
160e5c31af7Sopenharmony_ci};
161e5c31af7Sopenharmony_ci
162e5c31af7Sopenharmony_ci/** Constructor.
163e5c31af7Sopenharmony_ci	 *
164e5c31af7Sopenharmony_ci	 *  @param context     Rendering context
165e5c31af7Sopenharmony_ci	 *  @param name        Test name
166e5c31af7Sopenharmony_ci	 *  @param description Test description
167e5c31af7Sopenharmony_ci	 */
168e5c31af7Sopenharmony_ciSeparableProgramTFTestCase::SeparableProgramTFTestCase(deqp::Context& context, const char* name,
169e5c31af7Sopenharmony_ci													   PerStageData shaderData, GLint expectedValue)
170e5c31af7Sopenharmony_ci	: deqp::TestCase(context, name, ""), m_shaderData(shaderData), m_expectedValue(expectedValue)
171e5c31af7Sopenharmony_ci{
172e5c31af7Sopenharmony_ci}
173e5c31af7Sopenharmony_ci
174e5c31af7Sopenharmony_citcu::TestNode::IterateResult SeparableProgramTFTestCase::iterate(void)
175e5c31af7Sopenharmony_ci{
176e5c31af7Sopenharmony_ci	const Functions& gl			 = m_context.getRenderContext().getFunctions();
177e5c31af7Sopenharmony_ci	ContextType		 contextType = m_context.getRenderContext().getType();
178e5c31af7Sopenharmony_ci	GLSLVersion		 glslVersion = getContextTypeGLSLVersion(contextType);
179e5c31af7Sopenharmony_ci
180e5c31af7Sopenharmony_ci	/* For core GL gl_PerVertex interface block is combined from two parts.
181e5c31af7Sopenharmony_ci	 * First part contains definition and the second part name, which is
182e5c31af7Sopenharmony_ci	 * only specified for tess control stage (arrays are used here to avoid
183e5c31af7Sopenharmony_ci	 * three branches in a loop). For ES both parts are empty string */
184e5c31af7Sopenharmony_ci	const char*  blockName[STAGES_COUNT]	  = { "", ";\n", " gl_out[];\n", ";\n", ";\n" };
185e5c31af7Sopenharmony_ci	const char*  blockEmptyName[STAGES_COUNT] = { "", "", "", "", "" };
186e5c31af7Sopenharmony_ci	std::string  vertexBlock("");
187e5c31af7Sopenharmony_ci	const char** vertexBlockPostfix = blockEmptyName;
188e5c31af7Sopenharmony_ci	if (isContextTypeGLCore(contextType))
189e5c31af7Sopenharmony_ci	{
190e5c31af7Sopenharmony_ci		vertexBlock = "out gl_PerVertex"
191e5c31af7Sopenharmony_ci					  "{\n"
192e5c31af7Sopenharmony_ci					  "    vec4 gl_Position;\n"
193e5c31af7Sopenharmony_ci					  "}";
194e5c31af7Sopenharmony_ci		vertexBlockPostfix = blockName;
195e5c31af7Sopenharmony_ci	}
196e5c31af7Sopenharmony_ci
197e5c31af7Sopenharmony_ci	/* Construct specialization map - some specializations differ per stage */
198e5c31af7Sopenharmony_ci	std::map<std::string, std::string> specializationMap;
199e5c31af7Sopenharmony_ci	specializationMap["VERSION"] = glu::getGLSLVersionDeclaration(glslVersion);
200e5c31af7Sopenharmony_ci
201e5c31af7Sopenharmony_ci	/* Create separate programs - start from vertex stage to catch varying names */
202e5c31af7Sopenharmony_ci	std::vector<Utils::program> programs(STAGES_COUNT, Utils::program(m_context));
203e5c31af7Sopenharmony_ci	const char*					code[STAGES_COUNT] = { 0, 0, 0, 0, 0 };
204e5c31af7Sopenharmony_ci	for (int stageIndex = VERTEX_STAGE; stageIndex > -1; --stageIndex)
205e5c31af7Sopenharmony_ci	{
206e5c31af7Sopenharmony_ci		StageData*  stageData = m_shaderData.stage + stageIndex;
207e5c31af7Sopenharmony_ci		std::string source	= stageData->source;
208e5c31af7Sopenharmony_ci		if (source.empty())
209e5c31af7Sopenharmony_ci			continue;
210e5c31af7Sopenharmony_ci		specializationMap["PERVERTEX_BLOCK"] = vertexBlock + vertexBlockPostfix[stageIndex];
211e5c31af7Sopenharmony_ci		std::string specializedShader		 = StringTemplate(source).specialize(specializationMap);
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci		code[stageIndex] = specializedShader.c_str();
214e5c31af7Sopenharmony_ci		programs[stageIndex].build(0, code[0], code[1], code[2], code[3], code[4], stageData->tfVaryings,
215e5c31af7Sopenharmony_ci								   stageData->tfVaryingsCount, true);
216e5c31af7Sopenharmony_ci		code[stageIndex] = 0;
217e5c31af7Sopenharmony_ci
218e5c31af7Sopenharmony_ci		/* Use varying name from current stage to specialize next stage */
219e5c31af7Sopenharmony_ci		if (stageData->tfVaryings)
220e5c31af7Sopenharmony_ci			specializationMap["IN_VARYING_NAME"] = stageData->tfVaryings[0];
221e5c31af7Sopenharmony_ci	}
222e5c31af7Sopenharmony_ci
223e5c31af7Sopenharmony_ci	/* Create program pipeline */
224e5c31af7Sopenharmony_ci	GLuint pipelineId;
225e5c31af7Sopenharmony_ci	gl.genProgramPipelines(1, &pipelineId);
226e5c31af7Sopenharmony_ci	gl.bindProgramPipeline(pipelineId);
227e5c31af7Sopenharmony_ci	for (int stageIndex = 0; stageIndex < STAGES_COUNT; ++stageIndex)
228e5c31af7Sopenharmony_ci	{
229e5c31af7Sopenharmony_ci		if (!programs[stageIndex].m_program_object_id)
230e5c31af7Sopenharmony_ci			continue;
231e5c31af7Sopenharmony_ci		gl.useProgramStages(pipelineId, StageTokens[stageIndex], programs[stageIndex].m_program_object_id);
232e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgramStages() call failed.");
233e5c31af7Sopenharmony_ci	}
234e5c31af7Sopenharmony_ci
235e5c31af7Sopenharmony_ci	/* Validate the pipeline */
236e5c31af7Sopenharmony_ci	GLint validateStatus = GL_FALSE;
237e5c31af7Sopenharmony_ci	gl.validateProgramPipeline(pipelineId);
238e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glValidateProgramPipeline() call failed.");
239e5c31af7Sopenharmony_ci	gl.getProgramPipelineiv(pipelineId, GL_VALIDATE_STATUS, &validateStatus);
240e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramPipelineiv() call failed.");
241e5c31af7Sopenharmony_ci	if (validateStatus != GL_TRUE)
242e5c31af7Sopenharmony_ci	{
243e5c31af7Sopenharmony_ci		GLint logLength;
244e5c31af7Sopenharmony_ci		gl.getProgramPipelineiv(pipelineId, GL_INFO_LOG_LENGTH, &logLength);
245e5c31af7Sopenharmony_ci		if (logLength)
246e5c31af7Sopenharmony_ci		{
247e5c31af7Sopenharmony_ci			std::vector<GLchar> logBuffer(logLength + 1);
248e5c31af7Sopenharmony_ci			gl.getProgramPipelineInfoLog(pipelineId, logLength + 1, NULL, &logBuffer[0]);
249e5c31af7Sopenharmony_ci			m_context.getTestContext().getLog() << tcu::TestLog::Message << &logBuffer[0] << tcu::TestLog::EndMessage;
250e5c31af7Sopenharmony_ci		}
251e5c31af7Sopenharmony_ci		TCU_FAIL("Program pipeline has not been validated successfully.");
252e5c31af7Sopenharmony_ci	}
253e5c31af7Sopenharmony_ci
254e5c31af7Sopenharmony_ci	/* Generate buffer object to hold result XFB data */
255e5c31af7Sopenharmony_ci	Utils::buffer tfb(m_context);
256e5c31af7Sopenharmony_ci	GLsizeiptr	tfbSize = 100;
257e5c31af7Sopenharmony_ci	tfb.generate(GL_TRANSFORM_FEEDBACK_BUFFER);
258e5c31af7Sopenharmony_ci	tfb.update(tfbSize, 0 /* data */, GL_DYNAMIC_COPY);
259e5c31af7Sopenharmony_ci	tfb.bindRange(0, 0, tfbSize);
260e5c31af7Sopenharmony_ci
261e5c31af7Sopenharmony_ci	/* Generate VAO to use for the draw calls */
262e5c31af7Sopenharmony_ci	Utils::vertexArray vao(m_context);
263e5c31af7Sopenharmony_ci	vao.generate();
264e5c31af7Sopenharmony_ci	vao.bind();
265e5c31af7Sopenharmony_ci
266e5c31af7Sopenharmony_ci	/* Generate query object */
267e5c31af7Sopenharmony_ci	GLuint queryId;
268e5c31af7Sopenharmony_ci	gl.genQueries(1, &queryId);
269e5c31af7Sopenharmony_ci
270e5c31af7Sopenharmony_ci	/* Check if tessellation stage is active */
271e5c31af7Sopenharmony_ci	GLenum drawMode = GL_POINTS;
272e5c31af7Sopenharmony_ci	if (strlen(m_shaderData.stage[TESSELLATION_CONTROL_STAGE].source) > 0)
273e5c31af7Sopenharmony_ci		drawMode = GL_PATCHES;
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci	/* Draw and capture data */
276e5c31af7Sopenharmony_ci	gl.beginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queryId);
277e5c31af7Sopenharmony_ci	gl.beginTransformFeedback(GL_POINTS);
278e5c31af7Sopenharmony_ci	gl.patchParameteri(GL_PATCH_VERTICES, 1);
279e5c31af7Sopenharmony_ci	gl.drawArrays(drawMode, 0 /* first */, 1 /* count */);
280e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays() call failed.");
281e5c31af7Sopenharmony_ci	gl.endTransformFeedback();
282e5c31af7Sopenharmony_ci	gl.endQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
283e5c31af7Sopenharmony_ci
284e5c31af7Sopenharmony_ci	/* Get TF results */
285e5c31af7Sopenharmony_ci	GLuint writtenPrimitives = 0;
286e5c31af7Sopenharmony_ci	gl.getQueryObjectuiv(queryId, GL_QUERY_RESULT, &writtenPrimitives);
287e5c31af7Sopenharmony_ci	GLint* feedbackData = (GLint*)gl.mapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, tfbSize, GL_MAP_READ_BIT);
288e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer");
289e5c31af7Sopenharmony_ci
290e5c31af7Sopenharmony_ci	/* Verify if only values from upstream shader were captured */
291e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
292e5c31af7Sopenharmony_ci	if (writtenPrimitives != 0)
293e5c31af7Sopenharmony_ci	{
294e5c31af7Sopenharmony_ci		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
295e5c31af7Sopenharmony_ci		for (GLuint dataIndex = 0; dataIndex < writtenPrimitives; ++dataIndex)
296e5c31af7Sopenharmony_ci		{
297e5c31af7Sopenharmony_ci			if (feedbackData[dataIndex] == m_expectedValue)
298e5c31af7Sopenharmony_ci				continue;
299e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
300e5c31af7Sopenharmony_ci			break;
301e5c31af7Sopenharmony_ci		}
302e5c31af7Sopenharmony_ci	}
303e5c31af7Sopenharmony_ci
304e5c31af7Sopenharmony_ci	/* Cleanup */
305e5c31af7Sopenharmony_ci	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
306e5c31af7Sopenharmony_ci	gl.deleteQueries(1, &queryId);
307e5c31af7Sopenharmony_ci	gl.bindProgramPipeline(0);
308e5c31af7Sopenharmony_ci	gl.deleteProgramPipelines(1, &pipelineId);
309e5c31af7Sopenharmony_ci
310e5c31af7Sopenharmony_ci	return STOP;
311e5c31af7Sopenharmony_ci}
312e5c31af7Sopenharmony_ci
313e5c31af7Sopenharmony_ci/** Constructor.
314e5c31af7Sopenharmony_ci	 *
315e5c31af7Sopenharmony_ci	 *  @param context Rendering context.
316e5c31af7Sopenharmony_ci	 */
317e5c31af7Sopenharmony_ciSeparableProgramsTransformFeedbackTests::SeparableProgramsTransformFeedbackTests(deqp::Context& context)
318e5c31af7Sopenharmony_ci	: deqp::TestCaseGroup(context, "separable_programs_tf", "")
319e5c31af7Sopenharmony_ci{
320e5c31af7Sopenharmony_ci}
321e5c31af7Sopenharmony_ci
322e5c31af7Sopenharmony_ci/** Initializes the test group contents. */
323e5c31af7Sopenharmony_civoid SeparableProgramsTransformFeedbackTests::init(void)
324e5c31af7Sopenharmony_ci{
325e5c31af7Sopenharmony_ci	PerStageData tessellation_active = { {
326e5c31af7Sopenharmony_ci		{ fs_code, NULL, 0 },			  // fragment stage
327e5c31af7Sopenharmony_ci		{ "", NULL, 0 },				  // geometry stage
328e5c31af7Sopenharmony_ci		{ tcs_code, NULL, 0 },			  // tesselation control stage
329e5c31af7Sopenharmony_ci		{ tes_code, tes_tf_varyings, 1 }, // tesselation evaluation stage
330e5c31af7Sopenharmony_ci		{ vs_code, vs_tf_varyings, 1 }	// vertex_stage
331e5c31af7Sopenharmony_ci	} };
332e5c31af7Sopenharmony_ci	PerStageData geometry_active = { {
333e5c31af7Sopenharmony_ci		{ fs_code, NULL, 0 },			  // fragment stage
334e5c31af7Sopenharmony_ci		{ gs_code, gs_tf_varyings, 1 },   // geometry stage
335e5c31af7Sopenharmony_ci		{ tcs_code, NULL, 0 },			  // tesselation control stage
336e5c31af7Sopenharmony_ci		{ tes_code, tes_tf_varyings, 1 }, // tesselation evaluation stage
337e5c31af7Sopenharmony_ci		{ vs_code, vs_tf_varyings, 1 }	// vertex_stage
338e5c31af7Sopenharmony_ci	} };
339e5c31af7Sopenharmony_ci
340e5c31af7Sopenharmony_ci	addChild(new SeparableProgramTFTestCase(m_context, "tessellation_active", tessellation_active, 2));
341e5c31af7Sopenharmony_ci	addChild(new SeparableProgramTFTestCase(m_context, "geometry_active", geometry_active, 3));
342e5c31af7Sopenharmony_ci}
343e5c31af7Sopenharmony_ci
344e5c31af7Sopenharmony_ci} /* glcts namespace */
345