1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.1 Module
3e5c31af7Sopenharmony_ci * -------------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2015 The Android Open Source Project
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
21e5c31af7Sopenharmony_ci * \brief Program Pipeline State Query tests.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es31fProgramPipelineStateQueryTests.hpp"
25e5c31af7Sopenharmony_ci#include "es31fInfoLogQueryShared.hpp"
26e5c31af7Sopenharmony_ci#include "glsStateQueryUtil.hpp"
27e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp"
28e5c31af7Sopenharmony_ci#include "gluCallLogWrapper.hpp"
29e5c31af7Sopenharmony_ci#include "gluObjectWrapper.hpp"
30e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
31e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
32e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
33e5c31af7Sopenharmony_ci
34e5c31af7Sopenharmony_cinamespace deqp
35e5c31af7Sopenharmony_ci{
36e5c31af7Sopenharmony_cinamespace gles31
37e5c31af7Sopenharmony_ci{
38e5c31af7Sopenharmony_cinamespace Functional
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_cinamespace
41e5c31af7Sopenharmony_ci{
42e5c31af7Sopenharmony_ci
43e5c31af7Sopenharmony_ciusing namespace gls::StateQueryUtil;
44e5c31af7Sopenharmony_ci
45e5c31af7Sopenharmony_cistatic const char* getVerifierSuffix (QueryType type)
46e5c31af7Sopenharmony_ci{
47e5c31af7Sopenharmony_ci	switch (type)
48e5c31af7Sopenharmony_ci	{
49e5c31af7Sopenharmony_ci		case QUERY_PIPELINE_INTEGER:	return "get_program_pipelineiv";
50e5c31af7Sopenharmony_ci		default:
51e5c31af7Sopenharmony_ci			DE_ASSERT(DE_FALSE);
52e5c31af7Sopenharmony_ci			return DE_NULL;
53e5c31af7Sopenharmony_ci	}
54e5c31af7Sopenharmony_ci}
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_cistatic const char* const s_vertexSource =		"#version 310 es\n"
57e5c31af7Sopenharmony_ci												"out highp vec4 v_color;\n"
58e5c31af7Sopenharmony_ci												"void main()\n"
59e5c31af7Sopenharmony_ci												"{\n"
60e5c31af7Sopenharmony_ci												"	gl_Position = vec4(float(gl_VertexID) * 0.5, float(gl_VertexID+1) * 0.5, 0.0, 1.0);\n"
61e5c31af7Sopenharmony_ci												"	v_color = vec4(float(gl_VertexID), 1.0, 0.0, 1.0);\n"
62e5c31af7Sopenharmony_ci												"}\n";
63e5c31af7Sopenharmony_cistatic const char* const s_fragmentSource =		"#version 310 es\n"
64e5c31af7Sopenharmony_ci												"in highp vec4 v_color;\n"
65e5c31af7Sopenharmony_ci												"layout(location=0) out highp vec4 o_color;\n"
66e5c31af7Sopenharmony_ci												"void main()\n"
67e5c31af7Sopenharmony_ci												"{\n"
68e5c31af7Sopenharmony_ci												"	o_color = v_color;\n"
69e5c31af7Sopenharmony_ci												"}\n";
70e5c31af7Sopenharmony_cistatic const char* const s_computeSource =		"#version 310 es\n"
71e5c31af7Sopenharmony_ci												"layout (local_size_x = 1, local_size_y = 1) in;\n"
72e5c31af7Sopenharmony_ci												"layout(binding = 0) buffer Output\n"
73e5c31af7Sopenharmony_ci												"{\n"
74e5c31af7Sopenharmony_ci												"	highp float val;\n"
75e5c31af7Sopenharmony_ci												"} sb_out;\n"
76e5c31af7Sopenharmony_ci												"\n"
77e5c31af7Sopenharmony_ci												"void main (void)\n"
78e5c31af7Sopenharmony_ci												"{\n"
79e5c31af7Sopenharmony_ci												"	sb_out.val = 1.0;\n"
80e5c31af7Sopenharmony_ci												"}\n";
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ciclass ActiveProgramCase : public TestCase
83e5c31af7Sopenharmony_ci{
84e5c31af7Sopenharmony_cipublic:
85e5c31af7Sopenharmony_ci						ActiveProgramCase	(Context& context, QueryType verifier, const char* name, const char* desc);
86e5c31af7Sopenharmony_ci	IterateResult		iterate				(void);
87e5c31af7Sopenharmony_ci
88e5c31af7Sopenharmony_ciprivate:
89e5c31af7Sopenharmony_ci	const QueryType		m_verifier;
90e5c31af7Sopenharmony_ci};
91e5c31af7Sopenharmony_ci
92e5c31af7Sopenharmony_ciActiveProgramCase::ActiveProgramCase (Context& context, QueryType verifier, const char* name, const char* desc)
93e5c31af7Sopenharmony_ci	: TestCase		(context, name, desc)
94e5c31af7Sopenharmony_ci	, m_verifier	(verifier)
95e5c31af7Sopenharmony_ci{
96e5c31af7Sopenharmony_ci}
97e5c31af7Sopenharmony_ci
98e5c31af7Sopenharmony_ciActiveProgramCase::IterateResult ActiveProgramCase::iterate (void)
99e5c31af7Sopenharmony_ci{
100e5c31af7Sopenharmony_ci	const glu::ShaderProgram	vtxProgram	(m_context.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(s_vertexSource));
101e5c31af7Sopenharmony_ci	const glu::ShaderProgram	frgProgram	(m_context.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::FragmentSource(s_fragmentSource));
102e5c31af7Sopenharmony_ci	const glu::ProgramPipeline	pipeline	(m_context.getRenderContext());
103e5c31af7Sopenharmony_ci	glu::CallLogWrapper			gl			(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
104e5c31af7Sopenharmony_ci	tcu::ResultCollector		result		(m_testCtx.getLog(), " // ERROR: ");
105e5c31af7Sopenharmony_ci
106e5c31af7Sopenharmony_ci	{
107e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "VtxProg", "Vertex program");
108e5c31af7Sopenharmony_ci		m_testCtx.getLog() << vtxProgram;
109e5c31af7Sopenharmony_ci	}
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_ci	{
112e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "FrgProg", "Fragment program");
113e5c31af7Sopenharmony_ci		m_testCtx.getLog() << frgProgram;
114e5c31af7Sopenharmony_ci	}
115e5c31af7Sopenharmony_ci
116e5c31af7Sopenharmony_ci	if (!vtxProgram.isOk() || !frgProgram.isOk())
117e5c31af7Sopenharmony_ci		throw tcu::TestError("failed to build program");
118e5c31af7Sopenharmony_ci
119e5c31af7Sopenharmony_ci	gl.enableLogging(true);
120e5c31af7Sopenharmony_ci	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
121e5c31af7Sopenharmony_ci
122e5c31af7Sopenharmony_ci	gl.glBindProgramPipeline(pipeline.getPipeline());
123e5c31af7Sopenharmony_ci	gl.glUseProgramStages(pipeline.getPipeline(), GL_VERTEX_SHADER_BIT, vtxProgram.getProgram());
124e5c31af7Sopenharmony_ci	gl.glUseProgramStages(pipeline.getPipeline(), GL_FRAGMENT_SHADER_BIT, frgProgram.getProgram());
125e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen pipeline");
126e5c31af7Sopenharmony_ci	gl.glBindProgramPipeline(0);
127e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.glGetError(), "unbind pipeline");
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci	{
130e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial");
131e5c31af7Sopenharmony_ci		verifyStatePipelineInteger(result, gl, pipeline.getPipeline(), GL_ACTIVE_PROGRAM, 0, m_verifier);
132e5c31af7Sopenharmony_ci	}
133e5c31af7Sopenharmony_ci
134e5c31af7Sopenharmony_ci	{
135e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Set", "Set");
136e5c31af7Sopenharmony_ci
137e5c31af7Sopenharmony_ci		gl.glActiveShaderProgram(pipeline.getPipeline(), frgProgram.getProgram());
138e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen pipeline");
139e5c31af7Sopenharmony_ci		verifyStatePipelineInteger(result, gl, pipeline.getPipeline(), GL_ACTIVE_PROGRAM, (int)frgProgram.getProgram(), m_verifier);
140e5c31af7Sopenharmony_ci	}
141e5c31af7Sopenharmony_ci
142e5c31af7Sopenharmony_ci	result.setTestContextResult(m_testCtx);
143e5c31af7Sopenharmony_ci	return STOP;
144e5c31af7Sopenharmony_ci}
145e5c31af7Sopenharmony_ci
146e5c31af7Sopenharmony_ciclass PipelineProgramCase : public TestCase
147e5c31af7Sopenharmony_ci{
148e5c31af7Sopenharmony_cipublic:
149e5c31af7Sopenharmony_ci						PipelineProgramCase	(Context& context, QueryType verifier, const char* name, const char* desc, glw::GLenum stage);
150e5c31af7Sopenharmony_ci	IterateResult		iterate				(void);
151e5c31af7Sopenharmony_ci
152e5c31af7Sopenharmony_ciprivate:
153e5c31af7Sopenharmony_ci	const QueryType		m_verifier;
154e5c31af7Sopenharmony_ci	const glw::GLenum	m_targetStage;
155e5c31af7Sopenharmony_ci};
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_ciPipelineProgramCase::PipelineProgramCase (Context& context, QueryType verifier, const char* name, const char* desc, glw::GLenum stage)
158e5c31af7Sopenharmony_ci	: TestCase		(context, name, desc)
159e5c31af7Sopenharmony_ci	, m_verifier	(verifier)
160e5c31af7Sopenharmony_ci	, m_targetStage	(stage)
161e5c31af7Sopenharmony_ci{
162e5c31af7Sopenharmony_ci}
163e5c31af7Sopenharmony_ci
164e5c31af7Sopenharmony_ciPipelineProgramCase::IterateResult PipelineProgramCase::iterate (void)
165e5c31af7Sopenharmony_ci{
166e5c31af7Sopenharmony_ci	glu::CallLogWrapper		gl			(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
167e5c31af7Sopenharmony_ci	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
168e5c31af7Sopenharmony_ci	const int				stageBit	= (m_targetStage == GL_VERTEX_SHADER)	? (GL_VERTEX_SHADER_BIT)
169e5c31af7Sopenharmony_ci										: (m_targetStage == GL_FRAGMENT_SHADER)	? (GL_FRAGMENT_SHADER_BIT)
170e5c31af7Sopenharmony_ci										: (GL_COMPUTE_SHADER_BIT);
171e5c31af7Sopenharmony_ci	glu::ProgramSources	sources;
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ci	if (m_targetStage == GL_VERTEX_SHADER)
174e5c31af7Sopenharmony_ci		sources << glu::ProgramSeparable(true) << glu::VertexSource(s_vertexSource);
175e5c31af7Sopenharmony_ci	else if (m_targetStage == GL_FRAGMENT_SHADER)
176e5c31af7Sopenharmony_ci		sources << glu::ProgramSeparable(true) << glu::FragmentSource(s_fragmentSource);
177e5c31af7Sopenharmony_ci	else if (m_targetStage == GL_COMPUTE_SHADER)
178e5c31af7Sopenharmony_ci		sources << glu::ProgramSeparable(true) << glu::ComputeSource(s_computeSource);
179e5c31af7Sopenharmony_ci	else
180e5c31af7Sopenharmony_ci		DE_ASSERT(false);
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_ci	gl.enableLogging(true);
183e5c31af7Sopenharmony_ci
184e5c31af7Sopenharmony_ci	{
185e5c31af7Sopenharmony_ci		glu::ShaderProgram program(m_context.getRenderContext(), sources);
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_ci		{
188e5c31af7Sopenharmony_ci			const tcu::ScopedLogSection section(m_testCtx.getLog(), "program", "Program");
189e5c31af7Sopenharmony_ci			m_testCtx.getLog() << program;
190e5c31af7Sopenharmony_ci		}
191e5c31af7Sopenharmony_ci
192e5c31af7Sopenharmony_ci		if (!program.isOk())
193e5c31af7Sopenharmony_ci			throw tcu::TestError("failed to build program");
194e5c31af7Sopenharmony_ci
195e5c31af7Sopenharmony_ci		{
196e5c31af7Sopenharmony_ci			const tcu::ScopedLogSection section		(m_testCtx.getLog(), "Initial", "Initial");
197e5c31af7Sopenharmony_ci			glu::ProgramPipeline		pipeline	(m_context.getRenderContext());
198e5c31af7Sopenharmony_ci
199e5c31af7Sopenharmony_ci			gl.glBindProgramPipeline(pipeline.getPipeline());
200e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup pipeline");
201e5c31af7Sopenharmony_ci
202e5c31af7Sopenharmony_ci			verifyStatePipelineInteger(result, gl, pipeline.getPipeline(), m_targetStage, 0, m_verifier);
203e5c31af7Sopenharmony_ci		}
204e5c31af7Sopenharmony_ci
205e5c31af7Sopenharmony_ci		{
206e5c31af7Sopenharmony_ci			const tcu::ScopedLogSection section		(m_testCtx.getLog(), "Set", "Set");
207e5c31af7Sopenharmony_ci			glu::ProgramPipeline		pipeline	(m_context.getRenderContext());
208e5c31af7Sopenharmony_ci
209e5c31af7Sopenharmony_ci			gl.glBindProgramPipeline(pipeline.getPipeline());
210e5c31af7Sopenharmony_ci			gl.glUseProgramStages(pipeline.getPipeline(), stageBit, program.getProgram());
211e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup pipeline");
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci			verifyStatePipelineInteger(result, gl, pipeline.getPipeline(), m_targetStage, program.getProgram(), m_verifier);
214e5c31af7Sopenharmony_ci		}
215e5c31af7Sopenharmony_ci	}
216e5c31af7Sopenharmony_ci
217e5c31af7Sopenharmony_ci	result.setTestContextResult(m_testCtx);
218e5c31af7Sopenharmony_ci	return STOP;
219e5c31af7Sopenharmony_ci}
220e5c31af7Sopenharmony_ci
221e5c31af7Sopenharmony_ciclass ValidateStatusCase : public TestCase
222e5c31af7Sopenharmony_ci{
223e5c31af7Sopenharmony_cipublic:
224e5c31af7Sopenharmony_ci						ValidateStatusCase	(Context& context, QueryType verifier, const char* name, const char* desc);
225e5c31af7Sopenharmony_ci	IterateResult		iterate				(void);
226e5c31af7Sopenharmony_ci
227e5c31af7Sopenharmony_ciprivate:
228e5c31af7Sopenharmony_ci	const QueryType		m_verifier;
229e5c31af7Sopenharmony_ci};
230e5c31af7Sopenharmony_ci
231e5c31af7Sopenharmony_ciValidateStatusCase::ValidateStatusCase (Context& context, QueryType verifier, const char* name, const char* desc)
232e5c31af7Sopenharmony_ci	: TestCase		(context, name, desc)
233e5c31af7Sopenharmony_ci	, m_verifier	(verifier)
234e5c31af7Sopenharmony_ci{
235e5c31af7Sopenharmony_ci}
236e5c31af7Sopenharmony_ci
237e5c31af7Sopenharmony_ciValidateStatusCase::IterateResult ValidateStatusCase::iterate (void)
238e5c31af7Sopenharmony_ci{
239e5c31af7Sopenharmony_ci	glu::ShaderProgram		vtxProgram	(m_context.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(s_vertexSource));
240e5c31af7Sopenharmony_ci	glu::ShaderProgram		frgProgram	(m_context.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::FragmentSource(s_fragmentSource));
241e5c31af7Sopenharmony_ci	glu::ProgramPipeline	pipeline	(m_context.getRenderContext());
242e5c31af7Sopenharmony_ci	glu::CallLogWrapper		gl			(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
243e5c31af7Sopenharmony_ci	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
244e5c31af7Sopenharmony_ci
245e5c31af7Sopenharmony_ci	{
246e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "VtxProg", "Vertex program");
247e5c31af7Sopenharmony_ci		m_testCtx.getLog() << vtxProgram;
248e5c31af7Sopenharmony_ci	}
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_ci	{
251e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "FrgProg", "Fragment program");
252e5c31af7Sopenharmony_ci		m_testCtx.getLog() << frgProgram;
253e5c31af7Sopenharmony_ci	}
254e5c31af7Sopenharmony_ci
255e5c31af7Sopenharmony_ci	if (!vtxProgram.isOk() || !frgProgram.isOk())
256e5c31af7Sopenharmony_ci		throw tcu::TestError("failed to build program");
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ci	gl.enableLogging(true);
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_ci	gl.glBindProgramPipeline(pipeline.getPipeline());
261e5c31af7Sopenharmony_ci	gl.glUseProgramStages(pipeline.getPipeline(), GL_VERTEX_SHADER_BIT, vtxProgram.getProgram());
262e5c31af7Sopenharmony_ci	gl.glUseProgramStages(pipeline.getPipeline(), GL_FRAGMENT_SHADER_BIT, frgProgram.getProgram());
263e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen pipeline");
264e5c31af7Sopenharmony_ci	gl.glBindProgramPipeline(0);
265e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.glGetError(), "unbind pipeline");
266e5c31af7Sopenharmony_ci
267e5c31af7Sopenharmony_ci	{
268e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Initial", "Initial");
269e5c31af7Sopenharmony_ci		verifyStatePipelineInteger(result, gl, pipeline.getPipeline(), GL_VALIDATE_STATUS, 0, m_verifier);
270e5c31af7Sopenharmony_ci	}
271e5c31af7Sopenharmony_ci
272e5c31af7Sopenharmony_ci	{
273e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "Set", "Validate");
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci		gl.glValidateProgramPipeline(pipeline.getPipeline());
276e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen pipeline");
277e5c31af7Sopenharmony_ci		verifyStatePipelineInteger(result, gl, pipeline.getPipeline(), GL_VALIDATE_STATUS, GL_TRUE, m_verifier);
278e5c31af7Sopenharmony_ci	}
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ci	result.setTestContextResult(m_testCtx);
281e5c31af7Sopenharmony_ci	return STOP;
282e5c31af7Sopenharmony_ci}
283e5c31af7Sopenharmony_ci
284e5c31af7Sopenharmony_ciclass InfoLogCase : public TestCase
285e5c31af7Sopenharmony_ci{
286e5c31af7Sopenharmony_cipublic:
287e5c31af7Sopenharmony_ci						InfoLogCase	(Context& context, const char* name, const char* desc);
288e5c31af7Sopenharmony_ci	IterateResult		iterate		(void);
289e5c31af7Sopenharmony_ci};
290e5c31af7Sopenharmony_ci
291e5c31af7Sopenharmony_ciInfoLogCase::InfoLogCase (Context& context, const char* name, const char* desc)
292e5c31af7Sopenharmony_ci	: TestCase(context, name, desc)
293e5c31af7Sopenharmony_ci{
294e5c31af7Sopenharmony_ci}
295e5c31af7Sopenharmony_ci
296e5c31af7Sopenharmony_ciInfoLogCase::IterateResult InfoLogCase::iterate (void)
297e5c31af7Sopenharmony_ci{
298e5c31af7Sopenharmony_ci	using gls::StateQueryUtil::StateQueryMemoryWriteGuard;
299e5c31af7Sopenharmony_ci
300e5c31af7Sopenharmony_ci	static const char* const s_incompatibleFragmentSource = "#version 310 es\n"
301e5c31af7Sopenharmony_ci															"in mediump vec2 v_colorB;\n"
302e5c31af7Sopenharmony_ci															"in mediump vec2 v_colorC;\n"
303e5c31af7Sopenharmony_ci															"layout(location=0) out highp vec4 o_color;\n"
304e5c31af7Sopenharmony_ci															"void main()\n"
305e5c31af7Sopenharmony_ci															"{\n"
306e5c31af7Sopenharmony_ci															"	o_color = v_colorB.xxyy + v_colorC.yyxy;\n"
307e5c31af7Sopenharmony_ci															"}\n";
308e5c31af7Sopenharmony_ci
309e5c31af7Sopenharmony_ci	glu::ShaderProgram		vtxProgram	(m_context.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::VertexSource(s_vertexSource));
310e5c31af7Sopenharmony_ci	glu::ShaderProgram		frgProgram	(m_context.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << glu::FragmentSource(s_incompatibleFragmentSource));
311e5c31af7Sopenharmony_ci	glu::CallLogWrapper		gl			(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
312e5c31af7Sopenharmony_ci	tcu::ResultCollector	result		(m_testCtx.getLog(), " // ERROR: ");
313e5c31af7Sopenharmony_ci
314e5c31af7Sopenharmony_ci	{
315e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "VtxProg", "Vertex program");
316e5c31af7Sopenharmony_ci		m_testCtx.getLog() << vtxProgram;
317e5c31af7Sopenharmony_ci	}
318e5c31af7Sopenharmony_ci
319e5c31af7Sopenharmony_ci	{
320e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section(m_testCtx.getLog(), "FrgProg", "Fragment program");
321e5c31af7Sopenharmony_ci		m_testCtx.getLog() << frgProgram;
322e5c31af7Sopenharmony_ci	}
323e5c31af7Sopenharmony_ci
324e5c31af7Sopenharmony_ci	if (!vtxProgram.isOk() || !frgProgram.isOk())
325e5c31af7Sopenharmony_ci		throw tcu::TestError("failed to build program");
326e5c31af7Sopenharmony_ci
327e5c31af7Sopenharmony_ci	gl.enableLogging(true);
328e5c31af7Sopenharmony_ci
329e5c31af7Sopenharmony_ci	{
330e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection section		(m_testCtx.getLog(), "Initial", "Initial");
331e5c31af7Sopenharmony_ci		glu::ProgramPipeline		pipeline	(m_context.getRenderContext());
332e5c31af7Sopenharmony_ci		std::string					buf			(3, 'X');
333e5c31af7Sopenharmony_ci		int							written		= -1;
334e5c31af7Sopenharmony_ci
335e5c31af7Sopenharmony_ci		verifyStatePipelineInteger(result, gl, pipeline.getPipeline(), GL_INFO_LOG_LENGTH, 0, QUERY_PIPELINE_INTEGER);
336e5c31af7Sopenharmony_ci
337e5c31af7Sopenharmony_ci		gl.glGetProgramPipelineInfoLog(pipeline.getPipeline(), 2, &written, &buf[0]);
338e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.glGetError(), "query log");
339e5c31af7Sopenharmony_ci
340e5c31af7Sopenharmony_ci		if (written == -1)
341e5c31af7Sopenharmony_ci			result.fail("'length' was not written to");
342e5c31af7Sopenharmony_ci		else if (written != 0)
343e5c31af7Sopenharmony_ci			result.fail("'length' was not 0");
344e5c31af7Sopenharmony_ci		else if (buf[0] != '\0')
345e5c31af7Sopenharmony_ci			result.fail("log was not 0-sized null-terminated string");
346e5c31af7Sopenharmony_ci		else if (buf[1] != 'X' || buf[2] != 'X')
347e5c31af7Sopenharmony_ci			result.fail("buffer after returned length modified");
348e5c31af7Sopenharmony_ci	}
349e5c31af7Sopenharmony_ci
350e5c31af7Sopenharmony_ci	{
351e5c31af7Sopenharmony_ci		const tcu::ScopedLogSection				superSection	(m_testCtx.getLog(), "ValidationFail", "Failed validation");
352e5c31af7Sopenharmony_ci		glu::ProgramPipeline					pipeline		(m_context.getRenderContext());
353e5c31af7Sopenharmony_ci		StateQueryMemoryWriteGuard<glw::GLint>	logLen;
354e5c31af7Sopenharmony_ci
355e5c31af7Sopenharmony_ci		gl.glBindProgramPipeline(pipeline.getPipeline());
356e5c31af7Sopenharmony_ci		gl.glUseProgramStages(pipeline.getPipeline(), GL_VERTEX_SHADER_BIT, vtxProgram.getProgram());
357e5c31af7Sopenharmony_ci		gl.glUseProgramStages(pipeline.getPipeline(), GL_FRAGMENT_SHADER_BIT, frgProgram.getProgram());
358e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen pipeline");
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_ci		gl.glBindProgramPipeline(0);
361e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.glGetError(), "unbind pipeline");
362e5c31af7Sopenharmony_ci		gl.glValidateProgramPipeline(pipeline.getPipeline());
363e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen pipeline");
364e5c31af7Sopenharmony_ci
365e5c31af7Sopenharmony_ci		gl.glGetProgramPipelineiv(pipeline.getPipeline(), GL_INFO_LOG_LENGTH, &logLen);
366e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.glGetError(), "get INFO_LOG_LENGTH");
367e5c31af7Sopenharmony_ci
368e5c31af7Sopenharmony_ci		if (logLen.verifyValidity(result))
369e5c31af7Sopenharmony_ci			verifyInfoLogQuery(result, gl, logLen, pipeline.getPipeline(), &glu::CallLogWrapper::glGetProgramPipelineInfoLog, "glGetProgramPipelineInfoLog");
370e5c31af7Sopenharmony_ci	}
371e5c31af7Sopenharmony_ci
372e5c31af7Sopenharmony_ci	result.setTestContextResult(m_testCtx);
373e5c31af7Sopenharmony_ci	return STOP;
374e5c31af7Sopenharmony_ci}
375e5c31af7Sopenharmony_ci
376e5c31af7Sopenharmony_ci} // anonymous
377e5c31af7Sopenharmony_ci
378e5c31af7Sopenharmony_ciProgramPipelineStateQueryTests::ProgramPipelineStateQueryTests (Context& context)
379e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "program_pipeline", "Program Pipeline State Query tests")
380e5c31af7Sopenharmony_ci{
381e5c31af7Sopenharmony_ci}
382e5c31af7Sopenharmony_ci
383e5c31af7Sopenharmony_ciProgramPipelineStateQueryTests::~ProgramPipelineStateQueryTests (void)
384e5c31af7Sopenharmony_ci{
385e5c31af7Sopenharmony_ci}
386e5c31af7Sopenharmony_ci
387e5c31af7Sopenharmony_civoid ProgramPipelineStateQueryTests::init (void)
388e5c31af7Sopenharmony_ci{
389e5c31af7Sopenharmony_ci	static const QueryType verifiers[] =
390e5c31af7Sopenharmony_ci	{
391e5c31af7Sopenharmony_ci		QUERY_PIPELINE_INTEGER,
392e5c31af7Sopenharmony_ci	};
393e5c31af7Sopenharmony_ci
394e5c31af7Sopenharmony_ci#define FOR_EACH_VERIFIER(X)																	\
395e5c31af7Sopenharmony_ci	do {																						\
396e5c31af7Sopenharmony_ci		for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)	\
397e5c31af7Sopenharmony_ci		{																						\
398e5c31af7Sopenharmony_ci			const char* verifierSuffix = getVerifierSuffix(verifiers[verifierNdx]);				\
399e5c31af7Sopenharmony_ci			const QueryType verifier = verifiers[verifierNdx];									\
400e5c31af7Sopenharmony_ci			this->addChild(X);																	\
401e5c31af7Sopenharmony_ci		}																						\
402e5c31af7Sopenharmony_ci	} while (0)
403e5c31af7Sopenharmony_ci
404e5c31af7Sopenharmony_ci	FOR_EACH_VERIFIER(new ActiveProgramCase(m_context, verifier, (std::string("active_program_") + verifierSuffix).c_str(), "Test ACTIVE_PROGRAM"));
405e5c31af7Sopenharmony_ci	FOR_EACH_VERIFIER(new PipelineProgramCase(m_context, verifier, (std::string("vertex_shader_") + verifierSuffix).c_str(), "Test VERTEX_SHADER", GL_VERTEX_SHADER));
406e5c31af7Sopenharmony_ci	FOR_EACH_VERIFIER(new PipelineProgramCase(m_context, verifier, (std::string("fragment_shader_") + verifierSuffix).c_str(), "Test FRAGMENT_SHADER", GL_FRAGMENT_SHADER));
407e5c31af7Sopenharmony_ci	FOR_EACH_VERIFIER(new PipelineProgramCase(m_context, verifier, (std::string("compute_shader_") + verifierSuffix).c_str(), "Test COMPUTE_SHADER", GL_COMPUTE_SHADER));
408e5c31af7Sopenharmony_ci	FOR_EACH_VERIFIER(new ValidateStatusCase(m_context, verifier, (std::string("validate_status_") + verifierSuffix).c_str(), "Test VALIDATE_STATUS"));
409e5c31af7Sopenharmony_ci
410e5c31af7Sopenharmony_ci#undef FOR_EACH_VERIFIER
411e5c31af7Sopenharmony_ci
412e5c31af7Sopenharmony_ci	this->addChild(new InfoLogCase(m_context, "info_log", "Test info log"));
413e5c31af7Sopenharmony_ci}
414e5c31af7Sopenharmony_ci
415e5c31af7Sopenharmony_ci} // Functional
416e5c31af7Sopenharmony_ci} // gles31
417e5c31af7Sopenharmony_ci} // deqp
418