1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2016 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 Shader Directive Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fNegativeShaderDirectiveTests.hpp"
25 
26 #include "gluShaderProgram.hpp"
27 
28 namespace deqp
29 {
30 namespace gles31
31 {
32 namespace Functional
33 {
34 namespace NegativeTestShared
35 {
36 namespace
37 {
38 
39 enum ExpectResult
40 {
41 	EXPECT_RESULT_PASS = 0,
42 	EXPECT_RESULT_FAIL,
43 
44 	EXPECT_RESULT_LAST
45 };
46 
verifyProgram(NegativeTestContext & ctx,glu::ProgramSources sources,ExpectResult expect)47 void verifyProgram(NegativeTestContext& ctx, glu::ProgramSources sources, ExpectResult expect)
48 {
49 	DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST);
50 
51 	tcu::TestLog& 				log 		= ctx.getLog();
52 	const glu::ShaderProgram 	program		(ctx.getRenderContext(), sources);
53 	bool						testFailed	= false;
54 	std::string					message;
55 
56 	log << program;
57 
58 	if (expect == EXPECT_RESULT_PASS)
59 	{
60 		testFailed = !program.getProgramInfo().linkOk;
61 		message = "Program did not link.";
62 	}
63 	else
64 	{
65 		testFailed = program.getProgramInfo().linkOk;
66 		message = "Program was not expected to link.";
67 	}
68 
69 	if (testFailed)
70 	{
71 		log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
72 		ctx.fail(message);
73 	}
74 }
75 
verifyShader(NegativeTestContext & ctx,glu::ShaderType shaderType,std::string shaderSource,ExpectResult expect)76 void verifyShader(NegativeTestContext& ctx, glu::ShaderType shaderType, std::string shaderSource, ExpectResult expect)
77 {
78 	DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST);
79 
80 	tcu::TestLog& 		log			= ctx.getLog();
81 	bool				testFailed	= false;
82 	const char* const	source		= shaderSource.c_str();
83 	const int			length		= (int) shaderSource.size();
84 	glu::Shader			shader		(ctx.getRenderContext(), shaderType);
85 	std::string			message;
86 
87 	shader.setSources(1, &source, &length);
88 	shader.compile();
89 
90 	log << shader;
91 
92 	if (expect == EXPECT_RESULT_PASS)
93 	{
94 		testFailed = !shader.getCompileStatus();
95 		message = "Shader did not compile.";
96 	}
97 	else
98 	{
99 		testFailed = shader.getCompileStatus();
100 		message = "Shader was not expected to compile.";
101 	}
102 
103 	if (testFailed)
104 	{
105 		log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
106 		ctx.fail(message);
107 	}
108 }
109 
primitive_bounding_box(NegativeTestContext & ctx)110 void primitive_bounding_box (NegativeTestContext& ctx)
111 {
112 	ctx.beginSection("GL_EXT_primitive_bounding_box features require enabling the extension in 310 es shaders.");
113 	{
114 		std::ostringstream source;
115 		source <<	"#version 310 es\n"
116 					"void main()\n"
117 					"{\n"
118 					"	gl_BoundingBoxEXT[0] = vec4(0.0, 0.0, 0.0, 0.0);\n"
119 					"	gl_BoundingBoxEXT[1] = vec4(1.0, 1.0, 1.0, 1.0);\n"
120 					"}\n";
121 		verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source.str(), EXPECT_RESULT_FAIL);
122 	}
123 	ctx.endSection();
124 
125 	if (contextSupports(ctx.getRenderContext().getType() , glu::ApiType::es(3, 2)))
126 	{
127 		ctx.beginSection("gl_BoundingBox does not require the OES/EXT suffix in a 320 es shader.");
128 		const std::string source =	"#version 320 es\n"
129 									"layout(vertices = 3) out;\n"
130 									"void main()\n"
131 									"{\n"
132 									"	gl_BoundingBox[0] = vec4(0.0, 0.0, 0.0, 0.0);\n"
133 									"	gl_BoundingBox[1] = vec4(0.0, 0.0, 0.0, 0.0);\n"
134 									"}\n";
135 		verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source, EXPECT_RESULT_PASS);
136 		ctx.endSection();
137 	}
138 }
139 
blend_equation_advanced(NegativeTestContext & ctx)140 void blend_equation_advanced (NegativeTestContext& ctx)
141 {
142 	static const char* const s_qualifiers[] =
143 	{
144 		"blend_support_multiply",
145 		"blend_support_screen",
146 		"blend_support_overlay",
147 		"blend_support_darken",
148 		"blend_support_lighten",
149 		"blend_support_colordodge",
150 		"blend_support_colorburn",
151 		"blend_support_hardlight",
152 		"blend_support_softlight",
153 		"blend_support_difference",
154 		"blend_support_exclusion",
155 		"blend_support_hsl_hue",
156 		"blend_support_hsl_saturation",
157 		"blend_support_hsl_color",
158 		"blend_support_hsl_luminosity",
159 	};
160 
161 	ctx.beginSection("GL_KHR_blend_equation_advanced features require enabling the extension in 310 es shaders.");
162 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_qualifiers); ++ndx)
163 	{
164 		std::ostringstream source;
165 		source <<	"#version 310 es\n"
166 					"layout(" << s_qualifiers[ndx] << ") out;\n"
167 					"void main()\n"
168 					"{\n"
169 					"}\n";
170 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
171 	}
172 	ctx.endSection();
173 }
174 
sample_variables(NegativeTestContext & ctx)175 void sample_variables (NegativeTestContext& ctx)
176 {
177 	TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType() , glu::ApiType::es(3, 2)), "Test requires a context version 3.2 or higher.");
178 
179 	static const char* const s_tests[] =
180 	{
181 		"int sampleId = gl_SampleID;",
182 		"vec2 samplePos = gl_SamplePosition;",
183 		"int sampleMaskIn0 = gl_SampleMaskIn[0];",
184 		"int sampleMask0 = gl_SampleMask[0];",
185 		"int numSamples = gl_NumSamples;",
186 	};
187 
188 	ctx.beginSection("GL_OES_sample_variables features require enabling the extension in 310 es shaders.");
189 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_tests); ++ndx)
190 	{
191 		std::ostringstream source;
192 		source <<	"#version 310 es\n"
193 					"precision mediump float;\n"
194 					"void main()\n"
195 					"{\n"
196 					"	" << s_tests[ndx] << "\n"
197 					"}\n";
198 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
199 	}
200 	ctx.endSection();
201 }
202 
shader_image_atomic(NegativeTestContext & ctx)203 void shader_image_atomic (NegativeTestContext& ctx)
204 {
205 	static const char* const s_tests[] =
206 	{
207 		"imageAtomicAdd(u_image, ivec2(1, 1), 1u);",
208 		"imageAtomicMin(u_image, ivec2(1, 1), 1u);",
209 		"imageAtomicMax(u_image, ivec2(1, 1), 1u);",
210 		"imageAtomicAnd(u_image, ivec2(1, 1), 1u);",
211 		"imageAtomicOr(u_image, ivec2(1, 1), 1u);",
212 		"imageAtomicXor(u_image, ivec2(1, 1), 1u);",
213 		"imageAtomicExchange(u_image, ivec2(1, 1), 1u);",
214 		"imageAtomicCompSwap(u_image, ivec2(1, 1), 1u, 1u);",
215 	};
216 
217 	ctx.beginSection("GL_OES_shader_image_atomic features require enabling the extension in 310 es shaders.");
218 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_tests); ++ndx)
219 	{
220 		std::ostringstream source;
221 		source <<	"#version 310 es\n"
222 					"layout(binding=0, r32ui) coherent uniform highp uimage2D u_image;\n"
223 					"precision mediump float;\n"
224 					"void main()\n"
225 					"{\n"
226 					"	" << s_tests[ndx] << "\n"
227 					"}\n";
228 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
229 	}
230 	ctx.endSection();
231 }
232 
shader_multisample_interpolation(NegativeTestContext & ctx)233 void shader_multisample_interpolation (NegativeTestContext& ctx)
234 {
235 	static const char* const s_sampleTests[] =
236 	{
237 		"sample in highp float v_var;",
238 		"sample out highp float v_var;"
239 	};
240 
241 	static const char* const s_interpolateAtTests[] =
242 	{
243 		"interpolateAtCentroid(interpolant);",
244 		"interpolateAtSample(interpolant, 1);",
245 		"interpolateAtOffset(interpolant, vec2(1.0, 0.0));"
246 	};
247 
248 	ctx.beginSection("GL_OES_shader_multisample_interpolation features require enabling the extension in 310 es shaders.");
249 	ctx.beginSection("Test sample in/out qualifiers.");
250 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_sampleTests); ++ndx)
251 	{
252 		std::ostringstream source;
253 		source <<	"#version 310 es\n"
254 					"	" << s_sampleTests[ndx] << "\n"
255 					"precision mediump float;\n"
256 					"void main()\n"
257 					"{\n"
258 					"}\n";
259 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
260 	}
261 	ctx.endSection();
262 
263 	ctx.beginSection("Test interpolateAt* functions.");
264 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_sampleTests); ++ndx)
265 	{
266 		std::ostringstream source;
267 		source <<	"#version 310 es\n"
268 					"in mediump float interpolant;\n"
269 					"precision mediump float;\n"
270 					"void main()\n"
271 					"{\n"
272 					"	" << s_interpolateAtTests[ndx] << "\n"
273 					"}\n";
274 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
275 	}
276 	ctx.endSection();
277 	ctx.endSection();
278 }
279 
texture_storage_multisample_2d_array(NegativeTestContext & ctx)280 void texture_storage_multisample_2d_array (NegativeTestContext& ctx)
281 {
282 	static const char* const s_samplerTypeTests[] =
283 	{
284 		"uniform mediump sampler2DMSArray u_sampler;",
285 		"uniform mediump isampler2DMSArray u_sampler;",
286 		"uniform mediump usampler2DMSArray u_sampler;",
287 	};
288 
289 	ctx.beginSection("GL_OES_texture_storage_multisample_2d_array features require enabling the extension in 310 es shaders.");
290 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerTypeTests); ++ndx)
291 	{
292 		std::ostringstream source;
293 		source <<	"#version 310 es\n"
294 					"	" << s_samplerTypeTests[ndx] << "\n"
295 					"precision mediump float;\n"
296 					"void main()\n"
297 					"{\n"
298 					"}\n";
299 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
300 	}
301 	ctx.endSection();
302 }
303 
geometry_shader(NegativeTestContext & ctx)304 void geometry_shader (NegativeTestContext& ctx)
305 {
306 	const std::string	simpleVtxFrag	=	"#version 310 es\n"
307 											"void main()\n"
308 											"{\n"
309 											"}\n";
310 	const std::string	geometry		=	"#version 310 es\n"
311 											"layout(points, invocations = 1) in;\n"
312 											"layout(points, max_vertices = 3) out;\n"
313 											"precision mediump float;\n"
314 											"void main()\n"
315 											"{\n"
316 											"	EmitVertex();\n"
317 											"	EndPrimitive();\n"
318 											"}\n";
319 	ctx.beginSection("GL_EXT_geometry_shader features require enabling the extension in 310 es shaders.");
320 	verifyProgram(ctx, glu::ProgramSources() << glu::VertexSource(simpleVtxFrag) << glu::GeometrySource(geometry) << glu::FragmentSource(simpleVtxFrag), EXPECT_RESULT_FAIL);
321 	ctx.endSection();
322 }
323 
gpu_shader_5(NegativeTestContext & ctx)324 void gpu_shader_5 (NegativeTestContext& ctx)
325 {
326 	ctx.beginSection("GL_EXT_gpu_shader5 features require enabling the extension in 310 es shaders.");
327 	ctx.beginSection("Testing the precise qualifier.");
328 	{
329 		std::ostringstream source;
330 		source <<	"#version 310 es\n"
331 					"void main()\n"
332 					"{\n"
333 					"	int low = 0;\n"
334 					"	int high = 10;\n"
335 					"	precise int middle = low + ((high - low) / 2);\n"
336 					"}\n";
337 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
338 	}
339 	ctx.endSection();
340 
341 	ctx.beginSection("Testing fused multiply-add.");
342 	{
343 		std::ostringstream source;
344 		source <<	"#version 310 es\n"
345 					"in mediump float v_var;"
346 					"void main()\n"
347 					"{\n"
348 					"	float fmaResult = fma(v_var, v_var, v_var);"
349 					"}\n";
350 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
351 	}
352 	ctx.endSection();
353 
354 	ctx.beginSection("Testing textureGatherOffsets.");
355 	{
356 		std::ostringstream source;
357 		source <<	"#version 310 es\n"
358 					"uniform mediump sampler2D u_tex;\n"
359 					"void main()\n"
360 					"{\n"
361 					"	highp vec2 coords = vec2(0.0, 1.0);\n"
362 					"	const ivec2 offsets[4] = ivec2[](ivec2(0,0), ivec2(1, 0), ivec2(0, 1), ivec2(1, 1));\n"
363 					"	textureGatherOffsets(u_tex, coords, offsets);\n"
364 					"}\n";
365 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
366 	}
367 	ctx.endSection();
368 
369 	ctx.endSection();
370 }
371 
shader_io_blocks(NegativeTestContext & ctx)372 void shader_io_blocks (NegativeTestContext& ctx)
373 {
374 	ctx.beginSection("GL_EXT_shader_io_blocks features require enabling the extension in 310 es shaders.");
375 	{
376 		std::ostringstream source;
377 		source <<	"#version 310 es\n"
378 					"in Data\n"
379 					"{\n"
380 					"	mediump vec3 a;\n"
381 					"} data;\n"
382 					"void main()\n"
383 					"{\n"
384 					"}\n";
385 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
386 	}
387 	ctx.endSection();
388 }
389 
tessellation_shader(NegativeTestContext & ctx)390 void tessellation_shader (NegativeTestContext& ctx)
391 {
392 	const std::string	simpleVtxFrag	=	"#version 310 es\n"
393 											"void main()\n"
394 											"{\n"
395 											"}\n";
396 	const std::string	tessControl		=	"#version 310 es\n"
397 											"layout(vertices = 3) out;\n"
398 											"void main()\n"
399 											"{\n"
400 											"}\n";
401 	const std::string	tessEvaluation	=	"#version 310 es\n"
402 											"layout(triangles, equal_spacing, cw) in;\n"
403 											"void main()\n"
404 											"{\n"
405 											"}\n";
406 	ctx.beginSection("GL_EXT_tessellation_shader features require enabling the extension in 310 es shaders.");
407 	glu::ProgramSources sources;
408 	sources << glu::VertexSource(simpleVtxFrag)
409 			<< glu::TessellationControlSource(tessControl)
410 			<< glu::TessellationEvaluationSource(tessEvaluation)
411 			<< glu::FragmentSource(simpleVtxFrag);
412 	verifyProgram(ctx, sources, EXPECT_RESULT_FAIL);
413 	ctx.endSection();
414 }
415 
texture_buffer(NegativeTestContext & ctx)416 void texture_buffer (NegativeTestContext& ctx)
417 {
418 	static const char* const s_samplerBufferTypes[] =
419 	{
420 		"uniform mediump samplerBuffer",
421 	    "uniform mediump isamplerBuffer",
422 	    "uniform mediump usamplerBuffer",
423 	    "layout(rgba32f) uniform mediump writeonly imageBuffer",
424 	    "layout(rgba32i) uniform mediump writeonly iimageBuffer",
425 	    "layout(rgba32ui) uniform mediump writeonly uimageBuffer"
426 	};
427 
428 	ctx.beginSection("GL_EXT_texture_buffer features require enabling the extension in 310 es shaders.");
429 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerBufferTypes); ++ndx)
430 	{
431 		std::ostringstream source;
432 		source <<	"#version 310 es\n"
433 					"" << s_samplerBufferTypes[ndx] << " u_buffer;\n"
434 					"void main()\n"
435 					"{\n"
436 					"}\n";
437 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
438 	}
439 	ctx.endSection();
440 }
441 
442 
texture_cube_map_array(NegativeTestContext & ctx)443 void texture_cube_map_array (NegativeTestContext& ctx)
444 {
445 	static const char* const s_samplerCubeArrayTypes[] =
446 	{
447 	    "uniform mediump samplerCubeArray",
448 	    "uniform mediump isamplerCubeArray",
449 	    "uniform mediump usamplerCubeArray",
450 	    "uniform mediump samplerCubeArrayShadow",
451 	    "layout(rgba32f) uniform mediump writeonly imageCubeArray",
452 	    "layout(rgba32i) uniform mediump writeonly iimageCubeArray",
453 	    "layout(rgba32ui) uniform mediump writeonly uimageCubeArray"
454 	};
455 
456 	ctx.beginSection("GL_EXT_texture_cube_map_array features require enabling the extension in 310 es shaders.");
457 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerCubeArrayTypes); ++ndx)
458 	{
459 		std::ostringstream source;
460 		source <<	"#version 310 es\n"
461 					"" << s_samplerCubeArrayTypes[ndx] << " u_cube;\n"
462 					"void main()\n"
463 					"{\n"
464 					"}\n";
465 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
466 	}
467 	ctx.endSection();
468 }
469 
470 } // anonymous
471 
getNegativeShaderDirectiveTestFunctions(void)472 std::vector<FunctionContainer> getNegativeShaderDirectiveTestFunctions (void)
473 {
474 	const FunctionContainer funcs[] =
475 	{
476 		{primitive_bounding_box,				"primitive_bounding_box",				"GL_EXT_primitive_bounding_box required in 310 es shaders to use AEP features. Version 320 es shaders do not require suffixes."	},
477 		{blend_equation_advanced,				"blend_equation_advanced",				"GL_KHR_blend_equation_advanced is required in 310 es shaders to use AEP features"												},
478 		{sample_variables,						"sample_variables",						"GL_OES_sample_variables is required in 310 es shaders to use AEP features"														},
479 		{shader_image_atomic,					"shader_image_atomic",					"GL_OES_shader_image_atomic is required in 310 es shaders to use AEP features"													},
480 		{shader_multisample_interpolation,		"shader_multisample_interpolation",		"GL_OES_shader_multisample_interpolation is required in 310 es shaders to use AEP features"										},
481 		{texture_storage_multisample_2d_array,	"texture_storage_multisample_2d_array",	"GL_OES_texture_storage_multisample_2d_array is required in 310 es shaders to use AEP features"									},
482 		{geometry_shader,						"geometry_shader",						"GL_EXT_geometry_shader is required in 310 es shaders to use AEP features"														},
483 		{gpu_shader_5,							"gpu_shader_5",							"GL_EXT_gpu_shader5 is required in 310 es shaders to use AEP features"															},
484 		{shader_io_blocks,						"shader_io_blocks",						"GL_EXT_shader_io_blocks is required in 310 es shaders to use AEP features"														},
485 		{tessellation_shader,					"tessellation_shader",					"GL_EXT_tessellation_shader is required in 310 es shaders to use AEP features"													},
486 		{texture_buffer,						"texture_buffer",						"GL_EXT_texture_buffer is required in 310 es shaders to use AEP features"														},
487 		{texture_cube_map_array,				"texture_cube_map_array",				"GL_EXT_texture_cube_map_array is required in 310 es shaders to use AEP features"												},
488 	};
489 
490 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
491 }
492 
493 } // NegativeTestShared
494 } // Functional
495 } // gles31
496 } // deqp
497