1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL ES 3.1 Module
3e5c31af7Sopenharmony_ci * -------------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2017 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 Negative ShaderFramebufferFetch tests.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es31fNegativeShaderFramebufferFetchTests.hpp"
25e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
26e5c31af7Sopenharmony_ci#include "gluShaderProgram.hpp"
27e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
28e5c31af7Sopenharmony_ci
29e5c31af7Sopenharmony_cinamespace deqp
30e5c31af7Sopenharmony_ci{
31e5c31af7Sopenharmony_ci
32e5c31af7Sopenharmony_ciusing std::string;
33e5c31af7Sopenharmony_ciusing std::map;
34e5c31af7Sopenharmony_ci
35e5c31af7Sopenharmony_cinamespace gles31
36e5c31af7Sopenharmony_ci{
37e5c31af7Sopenharmony_cinamespace Functional
38e5c31af7Sopenharmony_ci{
39e5c31af7Sopenharmony_cinamespace NegativeTestShared
40e5c31af7Sopenharmony_ci{
41e5c31af7Sopenharmony_cinamespace
42e5c31af7Sopenharmony_ci{
43e5c31af7Sopenharmony_ci
44e5c31af7Sopenharmony_cistatic const char* vertexShaderSource		=	"${GLSL_VERSION_STRING}\n"
45e5c31af7Sopenharmony_ci												"\n"
46e5c31af7Sopenharmony_ci												"void main (void)\n"
47e5c31af7Sopenharmony_ci												"{\n"
48e5c31af7Sopenharmony_ci												"	gl_Position = vec4(0.0);\n"
49e5c31af7Sopenharmony_ci												"}\n";
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_cistatic const char* fragmentShaderSource		=	"${GLSL_VERSION_STRING}\n"
52e5c31af7Sopenharmony_ci												"layout(location = 0) out mediump vec4 fragColor;\n"
53e5c31af7Sopenharmony_ci												"\n"
54e5c31af7Sopenharmony_ci												"void main (void)\n"
55e5c31af7Sopenharmony_ci												"{\n"
56e5c31af7Sopenharmony_ci												"	fragColor = vec4(1.0);\n"
57e5c31af7Sopenharmony_ci												"}\n";
58e5c31af7Sopenharmony_ci
59e5c31af7Sopenharmony_cistatic void checkExtensionSupport (NegativeTestContext& ctx, const char* extName)
60e5c31af7Sopenharmony_ci{
61e5c31af7Sopenharmony_ci	if (!ctx.getContextInfo().isExtensionSupported(extName))
62e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError(string(extName) + " not supported");
63e5c31af7Sopenharmony_ci}
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_cistatic void checkFramebufferFetchSupport (NegativeTestContext& ctx)
66e5c31af7Sopenharmony_ci{
67e5c31af7Sopenharmony_ci	checkExtensionSupport(ctx, "GL_EXT_shader_framebuffer_fetch");
68e5c31af7Sopenharmony_ci}
69e5c31af7Sopenharmony_ci
70e5c31af7Sopenharmony_cienum ProgramError
71e5c31af7Sopenharmony_ci{
72e5c31af7Sopenharmony_ci	PROGRAM_ERROR_LINK = 0,
73e5c31af7Sopenharmony_ci	PROGRAM_ERROR_COMPILE,
74e5c31af7Sopenharmony_ci	PROGRAM_ERROR_COMPILE_OR_LINK,
75e5c31af7Sopenharmony_ci};
76e5c31af7Sopenharmony_ci
77e5c31af7Sopenharmony_civoid verifyProgramError (NegativeTestContext& ctx, const glu::ShaderProgram& program,  ProgramError error, glu::ShaderType shaderType)
78e5c31af7Sopenharmony_ci{
79e5c31af7Sopenharmony_ci	bool	testFailed = false;
80e5c31af7Sopenharmony_ci	string	message;
81e5c31af7Sopenharmony_ci
82e5c31af7Sopenharmony_ci	ctx.getLog() << program;
83e5c31af7Sopenharmony_ci
84e5c31af7Sopenharmony_ci	switch (error)
85e5c31af7Sopenharmony_ci	{
86e5c31af7Sopenharmony_ci		case PROGRAM_ERROR_LINK:
87e5c31af7Sopenharmony_ci		{
88e5c31af7Sopenharmony_ci			message = "Program was not expected to link.";
89e5c31af7Sopenharmony_ci			testFailed = (program.getProgramInfo().linkOk);
90e5c31af7Sopenharmony_ci			break;
91e5c31af7Sopenharmony_ci		}
92e5c31af7Sopenharmony_ci		case PROGRAM_ERROR_COMPILE:
93e5c31af7Sopenharmony_ci		{
94e5c31af7Sopenharmony_ci			message = "Program was not expected to compile.";
95e5c31af7Sopenharmony_ci			testFailed = program.getShaderInfo(shaderType).compileOk;
96e5c31af7Sopenharmony_ci			break;
97e5c31af7Sopenharmony_ci		}
98e5c31af7Sopenharmony_ci		case PROGRAM_ERROR_COMPILE_OR_LINK:
99e5c31af7Sopenharmony_ci		{
100e5c31af7Sopenharmony_ci			message = "Program was not expected to compile or link.";
101e5c31af7Sopenharmony_ci			testFailed = (program.getProgramInfo().linkOk) && (program.getShaderInfo(shaderType).compileOk);
102e5c31af7Sopenharmony_ci			break;
103e5c31af7Sopenharmony_ci		}
104e5c31af7Sopenharmony_ci		default:
105e5c31af7Sopenharmony_ci		{
106e5c31af7Sopenharmony_ci			DE_FATAL("Invalid program error type");
107e5c31af7Sopenharmony_ci			break;
108e5c31af7Sopenharmony_ci		}
109e5c31af7Sopenharmony_ci	}
110e5c31af7Sopenharmony_ci
111e5c31af7Sopenharmony_ci	if (testFailed)
112e5c31af7Sopenharmony_ci	{
113e5c31af7Sopenharmony_ci		ctx.getLog() << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
114e5c31af7Sopenharmony_ci		ctx.fail(message);
115e5c31af7Sopenharmony_ci	}
116e5c31af7Sopenharmony_ci}
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_civoid last_frag_data_not_defined (NegativeTestContext& ctx)
119e5c31af7Sopenharmony_ci{
120e5c31af7Sopenharmony_ci	// this tests does not apply to GL4.5
121e5c31af7Sopenharmony_ci	if (!glu::isContextTypeES(ctx.getRenderContext().getType()))
122e5c31af7Sopenharmony_ci		return;
123e5c31af7Sopenharmony_ci
124e5c31af7Sopenharmony_ci	checkFramebufferFetchSupport(ctx);
125e5c31af7Sopenharmony_ci
126e5c31af7Sopenharmony_ci	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
127e5c31af7Sopenharmony_ci	map<string, string>			args;
128e5c31af7Sopenharmony_ci	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
129e5c31af7Sopenharmony_ci
130e5c31af7Sopenharmony_ci	const char* const fragShaderSource	=	"${GLSL_VERSION_STRING}\n"
131e5c31af7Sopenharmony_ci											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
132e5c31af7Sopenharmony_ci											"layout(location = 0) out mediump vec4 fragColor;\n"
133e5c31af7Sopenharmony_ci											"\n"
134e5c31af7Sopenharmony_ci											"void main (void)\n"
135e5c31af7Sopenharmony_ci											"{\n"
136e5c31af7Sopenharmony_ci											"	fragColor = gl_LastFragData[0];\n"
137e5c31af7Sopenharmony_ci											"}\n";
138e5c31af7Sopenharmony_ci
139e5c31af7Sopenharmony_ci	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
140e5c31af7Sopenharmony_ci			<< glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args))
141e5c31af7Sopenharmony_ci			<< glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
142e5c31af7Sopenharmony_ci
143e5c31af7Sopenharmony_ci	ctx.beginSection("A link error is generated if the built-in fragment outputs of ES 2.0 are used in #version 300 es shaders");
144e5c31af7Sopenharmony_ci	verifyProgramError(ctx, program, PROGRAM_ERROR_LINK, glu::SHADERTYPE_FRAGMENT);
145e5c31af7Sopenharmony_ci	ctx.endSection();
146e5c31af7Sopenharmony_ci}
147e5c31af7Sopenharmony_ci
148e5c31af7Sopenharmony_civoid last_frag_data_readonly (NegativeTestContext& ctx)
149e5c31af7Sopenharmony_ci{
150e5c31af7Sopenharmony_ci	return; /// TEMP - not sure what to do, this test crashes on es3.1 and gl4.5 context
151e5c31af7Sopenharmony_ci
152e5c31af7Sopenharmony_ci	checkFramebufferFetchSupport(ctx);
153e5c31af7Sopenharmony_ci
154e5c31af7Sopenharmony_ci	map<string, string>			args;
155e5c31af7Sopenharmony_ci	args["GLSL_VERSION_STRING"]			=	getGLSLVersionDeclaration(glu::GLSL_VERSION_100_ES);
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_ci	const char* const fragShaderSource	=	"${GLSL_VERSION_STRING}\n"
158e5c31af7Sopenharmony_ci											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
159e5c31af7Sopenharmony_ci											"\n"
160e5c31af7Sopenharmony_ci											"void main (void)\n"
161e5c31af7Sopenharmony_ci											"{\n"
162e5c31af7Sopenharmony_ci											"	gl_LastFragData[0] = vec4(1.0);\n"
163e5c31af7Sopenharmony_ci											"	gl_FragColor = gl_LastFragData[0];\n"
164e5c31af7Sopenharmony_ci											"}\n";
165e5c31af7Sopenharmony_ci
166e5c31af7Sopenharmony_ci	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
167e5c31af7Sopenharmony_ci			<< glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args))
168e5c31af7Sopenharmony_ci			<< glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
169e5c31af7Sopenharmony_ci
170e5c31af7Sopenharmony_ci	ctx.beginSection("A compile-time or link error is generated if the built-in fragment outputs of ES 2.0 are written to.");
171e5c31af7Sopenharmony_ci	verifyProgramError(ctx, program, PROGRAM_ERROR_COMPILE_OR_LINK, glu::SHADERTYPE_FRAGMENT);
172e5c31af7Sopenharmony_ci	ctx.endSection();
173e5c31af7Sopenharmony_ci}
174e5c31af7Sopenharmony_ci
175e5c31af7Sopenharmony_civoid invalid_inout_version (NegativeTestContext& ctx)
176e5c31af7Sopenharmony_ci{
177e5c31af7Sopenharmony_ci	checkFramebufferFetchSupport(ctx);
178e5c31af7Sopenharmony_ci
179e5c31af7Sopenharmony_ci	map<string, string>			args;
180e5c31af7Sopenharmony_ci	args["GLSL_VERSION_STRING"]			=	getGLSLVersionDeclaration(glu::GLSL_VERSION_100_ES);
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_ci	const char* const fragShaderSource	=	"${GLSL_VERSION_STRING}\n"
183e5c31af7Sopenharmony_ci											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
184e5c31af7Sopenharmony_ci											"inout highp vec4 fragColor;\n"
185e5c31af7Sopenharmony_ci											"\n"
186e5c31af7Sopenharmony_ci											"void main (void)\n"
187e5c31af7Sopenharmony_ci											"{\n"
188e5c31af7Sopenharmony_ci											"	highp float product = dot(vec3(0.5), fragColor.rgb);\n"
189e5c31af7Sopenharmony_ci											"	gl_FragColor = vec4(product);\n"
190e5c31af7Sopenharmony_ci											"}\n";
191e5c31af7Sopenharmony_ci
192e5c31af7Sopenharmony_ci	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
193e5c31af7Sopenharmony_ci			<< glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args))
194e5c31af7Sopenharmony_ci			<< glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
195e5c31af7Sopenharmony_ci
196e5c31af7Sopenharmony_ci	ctx.beginSection("A compile-time or link error is generated if user-defined inout arrays are used in earlier versions of GLSL before ES 3.0");
197e5c31af7Sopenharmony_ci	verifyProgramError(ctx, program, PROGRAM_ERROR_COMPILE_OR_LINK, glu::SHADERTYPE_FRAGMENT);
198e5c31af7Sopenharmony_ci	ctx.endSection();
199e5c31af7Sopenharmony_ci}
200e5c31af7Sopenharmony_ci
201e5c31af7Sopenharmony_civoid invalid_redeclaration_inout (NegativeTestContext& ctx)
202e5c31af7Sopenharmony_ci{
203e5c31af7Sopenharmony_ci	// this case does not apply to GL4.5
204e5c31af7Sopenharmony_ci	if (!glu::isContextTypeES(ctx.getRenderContext().getType()))
205e5c31af7Sopenharmony_ci		return;
206e5c31af7Sopenharmony_ci
207e5c31af7Sopenharmony_ci	checkFramebufferFetchSupport(ctx);
208e5c31af7Sopenharmony_ci
209e5c31af7Sopenharmony_ci	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
210e5c31af7Sopenharmony_ci	map<string, string>			args;
211e5c31af7Sopenharmony_ci	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci	const char* const fragShaderSource	=	"${GLSL_VERSION_STRING}\n"
214e5c31af7Sopenharmony_ci											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
215e5c31af7Sopenharmony_ci											"layout(location = 0) out mediump vec4 fragColor;\n"
216e5c31af7Sopenharmony_ci											"inout highp float gl_FragDepth;\n"
217e5c31af7Sopenharmony_ci											"\n"
218e5c31af7Sopenharmony_ci											"void main (void)\n"
219e5c31af7Sopenharmony_ci											"{\n"
220e5c31af7Sopenharmony_ci											"	gl_FragDepth += 0.5f;\n"
221e5c31af7Sopenharmony_ci											"	fragColor = vec4(1.0f);\n"
222e5c31af7Sopenharmony_ci											"}\n";
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_ci	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
225e5c31af7Sopenharmony_ci			<< glu::VertexSource(tcu::StringTemplate(vertexShaderSource).specialize(args))
226e5c31af7Sopenharmony_ci			<< glu::FragmentSource(tcu::StringTemplate(fragShaderSource).specialize(args)));
227e5c31af7Sopenharmony_ci
228e5c31af7Sopenharmony_ci	ctx.beginSection("A compile-time or link error is generated if re-declaring an existing fragment output such as gl_FragDepth as inout");
229e5c31af7Sopenharmony_ci	verifyProgramError(ctx, program, PROGRAM_ERROR_COMPILE_OR_LINK, glu::SHADERTYPE_FRAGMENT);
230e5c31af7Sopenharmony_ci	ctx.endSection();
231e5c31af7Sopenharmony_ci}
232e5c31af7Sopenharmony_ci
233e5c31af7Sopenharmony_civoid invalid_vertex_inout (NegativeTestContext& ctx)
234e5c31af7Sopenharmony_ci{
235e5c31af7Sopenharmony_ci	// this case does not apply to GL4.5
236e5c31af7Sopenharmony_ci	if (!glu::isContextTypeES(ctx.getRenderContext().getType()))
237e5c31af7Sopenharmony_ci		return;
238e5c31af7Sopenharmony_ci
239e5c31af7Sopenharmony_ci	checkFramebufferFetchSupport(ctx);
240e5c31af7Sopenharmony_ci
241e5c31af7Sopenharmony_ci	const bool					isES32	= glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
242e5c31af7Sopenharmony_ci	map<string, string>			args;
243e5c31af7Sopenharmony_ci	args["GLSL_VERSION_STRING"]			= isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
244e5c31af7Sopenharmony_ci
245e5c31af7Sopenharmony_ci	const char* const vertShaderSource	=	"${GLSL_VERSION_STRING}\n"
246e5c31af7Sopenharmony_ci											"#extension GL_EXT_shader_framebuffer_fetch : require\n"
247e5c31af7Sopenharmony_ci											"inout mediump vec4 v_color;\n"
248e5c31af7Sopenharmony_ci											"\n"
249e5c31af7Sopenharmony_ci											"void main (void)\n"
250e5c31af7Sopenharmony_ci											"{\n"
251e5c31af7Sopenharmony_ci											"}\n";
252e5c31af7Sopenharmony_ci
253e5c31af7Sopenharmony_ci	glu::ShaderProgram program(ctx.getRenderContext(), glu::ProgramSources()
254e5c31af7Sopenharmony_ci			<< glu::VertexSource(tcu::StringTemplate(vertShaderSource).specialize(args))
255e5c31af7Sopenharmony_ci			<< glu::FragmentSource(tcu::StringTemplate(fragmentShaderSource).specialize(args)));
256e5c31af7Sopenharmony_ci
257e5c31af7Sopenharmony_ci	ctx.beginSection("A compile-time error or link error is generated if inout variables are declared in the vertex shader\n");
258e5c31af7Sopenharmony_ci	verifyProgramError(ctx, program, PROGRAM_ERROR_COMPILE_OR_LINK, glu::SHADERTYPE_VERTEX);
259e5c31af7Sopenharmony_ci	ctx.endSection();
260e5c31af7Sopenharmony_ci}
261e5c31af7Sopenharmony_ci
262e5c31af7Sopenharmony_ci} // anonymous
263e5c31af7Sopenharmony_ci
264e5c31af7Sopenharmony_cistd::vector<FunctionContainer> getNegativeShaderFramebufferFetchTestFunctions (void)
265e5c31af7Sopenharmony_ci{
266e5c31af7Sopenharmony_ci	const FunctionContainer funcs[] =
267e5c31af7Sopenharmony_ci	{
268e5c31af7Sopenharmony_ci		{ last_frag_data_not_defined,		"last_frag_data_not_defined",		"The built-in gl_LastFragData not defined in #version 300 es shaders"				},
269e5c31af7Sopenharmony_ci		{ last_frag_data_readonly,			"last_frag_data_readonly",			"Invalid write to readonly builtin in gl_LastFragData"								},
270e5c31af7Sopenharmony_ci		{ invalid_inout_version,			"invalid_inout_version",			"Invalid use of user-defined inout arrays in versions before GLSL #version 300 es."	},
271e5c31af7Sopenharmony_ci		{ invalid_redeclaration_inout,		"invalid_redeclaration_inout",		"Existing fragment shader built-ins cannot be redeclared as inout arrays"			},
272e5c31af7Sopenharmony_ci		{ invalid_vertex_inout,				"invalid_vertex_inout",				"User defined inout arrays are not allowed in the vertex shader"					},
273e5c31af7Sopenharmony_ci	};
274e5c31af7Sopenharmony_ci
275e5c31af7Sopenharmony_ci	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
276e5c31af7Sopenharmony_ci}
277e5c31af7Sopenharmony_ci
278e5c31af7Sopenharmony_ci} // NegativeTestShared
279e5c31af7Sopenharmony_ci} // Functional
280e5c31af7Sopenharmony_ci} // gles31
281e5c31af7Sopenharmony_ci} // deqp
282