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