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