Home | History | Annotate | Download | only in functional
      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 Sample Variables Tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es31fNegativeSampleVariablesTests.hpp"
     25 #include "gluShaderProgram.hpp"
     26 
     27 namespace deqp
     28 {
     29 namespace gles31
     30 {
     31 namespace Functional
     32 {
     33 namespace NegativeTestShared
     34 {
     35 namespace
     36 {
     37 
     38 enum ExpectResult
     39 {
     40 	EXPECT_RESULT_PASS = 0,
     41 	EXPECT_RESULT_FAIL,
     42 	EXPECT_RESULT_LAST
     43 };
     44 
     45 void verifyShader (NegativeTestContext& ctx, glu::ShaderType shaderType, std::string shaderSource, ExpectResult expect)
     46 {
     47 	DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST);
     48 
     49 	tcu::TestLog&		log			= ctx.getLog();
     50 	bool				testFailed	= false;
     51 	const char* const	source		= shaderSource.c_str();
     52 	const int			length		= (int) shaderSource.size();
     53 	glu::Shader			shader		(ctx.getRenderContext(), shaderType);
     54 	std::string			message;
     55 
     56 	shader.setSources(1, &source, &length);
     57 	shader.compile();
     58 
     59 	log << shader;
     60 
     61 	if (expect == EXPECT_RESULT_PASS)
     62 	{
     63 		testFailed = !shader.getCompileStatus();
     64 		message = "Shader did not compile.";
     65 	}
     66 	else
     67 	{
     68 		testFailed = shader.getCompileStatus();
     69 		message = "Shader was not expected to compile.";
     70 	}
     71 
     72 	if (testFailed)
     73 	{
     74 		log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
     75 		ctx.fail(message);
     76 	}
     77 }
     78 
     79 std::string getVersionAndExtension (NegativeTestContext& ctx)
     80 {
     81 	const bool				isES32	= contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
     82 	const glu::GLSLVersion	version	= isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
     83 
     84 	std::string versionAndExtension = glu::getGLSLVersionDeclaration(version);
     85 	versionAndExtension += " \n";
     86 
     87 	if (!isES32)
     88 		versionAndExtension += "#extension GL_OES_sample_variables : require \n";
     89 
     90 	return versionAndExtension;
     91 }
     92 
     93 void checkSupported (NegativeTestContext& ctx)
     94 {
     95 	const bool isES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
     96 
     97 	if (!isES32 && !ctx.isExtensionSupported("GL_OES_sample_variables"))
     98 		TCU_THROW(NotSupportedError, "GL_OES_sample_variables is not supported.");
     99 }
    100 
    101 void write_to_read_only_types (NegativeTestContext& ctx)
    102 {
    103 	checkSupported(ctx);
    104 
    105 	std::ostringstream	shader;
    106 
    107 	struct testConfig
    108 	{
    109 		std::string builtInType;
    110 		std::string varyingCheck;
    111 	} testConfigs[] =
    112 	{
    113 		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
    114 		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
    115 		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"}
    116 	};
    117 
    118 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
    119 	{
    120 		shader.str("");
    121 		shader
    122 			<< getVersionAndExtension(ctx)
    123 			<< "layout (location = 0) out mediump vec4 fs_color; \n"
    124 			<< "void main() \n"
    125 			<< "{ \n"
    126 			<<		testConfigs[idx].varyingCheck
    127 			<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
    128 			<< "} \n";
    129 
    130 		ctx.beginSection("OES_sample_variables: trying to write to built-in read-only variable" + testConfigs[idx].builtInType);
    131 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
    132 		ctx.endSection();
    133 	}
    134 }
    135 
    136 void access_built_in_types_inside_other_shaders (NegativeTestContext& ctx)
    137 {
    138 	checkSupported(ctx);
    139 
    140 	if ((!ctx.isExtensionSupported("GL_EXT_tessellation_shader") && !ctx.isExtensionSupported("GL_OES_tessellation_shader")) ||
    141 		(!ctx.isExtensionSupported("GL_EXT_geometry_shader") && !ctx.isExtensionSupported("GL_OES_geometry_shader")))
    142 	{
    143 		TCU_THROW(NotSupportedError, "tessellation and geometry shader extensions not supported");
    144 	}
    145 
    146 	std::ostringstream	shader;
    147 
    148 	struct testConfig
    149 	{
    150 		std::string builtInType;
    151 		std::string varyingCheck;
    152 	} testConfigs[] =
    153 	{
    154 		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
    155 		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
    156 		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"},
    157 		{"gl_SampleMask",		"	highp int readValue = gl_SampleMask[0]; \n"},
    158 	};
    159 
    160 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
    161 	{
    162 		shader.str("");
    163 		shader
    164 			<< getVersionAndExtension(ctx)
    165 			<< "void main () \n"
    166 			<< "{ \n"
    167 			<<		testConfigs[idx].varyingCheck
    168 			<< "	gl_Position = vec4(1.0f, 0.0f, 0.0f , 1.0f); \n"
    169 			<< "} \n";
    170 
    171 		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside vertex shader");
    172 		verifyShader(ctx, glu::SHADERTYPE_VERTEX, shader.str(), EXPECT_RESULT_FAIL);
    173 		ctx.endSection();
    174 	}
    175 
    176 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
    177 	{
    178 		shader.str("");
    179 		shader
    180 			<< getVersionAndExtension(ctx)
    181 			<< "layout (vertices = 3) out; \n"
    182 			<< "void main () \n"
    183 			<< "{ \n"
    184 			<<		testConfigs[idx].varyingCheck
    185 			<< "} \n";
    186 
    187 		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside tessellation control shader");
    188 		verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, shader.str(), EXPECT_RESULT_FAIL);
    189 		ctx.endSection();
    190 	}
    191 
    192 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
    193 	{
    194 		shader.str("");
    195 		shader
    196 			<< getVersionAndExtension(ctx)
    197 			<< "layout (triangles, equal_spacing, ccw) in; \n"
    198 			<< "void main () \n"
    199 			<< "{ \n"
    200 			<<		testConfigs[idx].varyingCheck
    201 			<< "} \n";
    202 
    203 		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside tessellation evaluation shader");
    204 		verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_EVALUATION, shader.str(), EXPECT_RESULT_FAIL);
    205 		ctx.endSection();
    206 	}
    207 
    208 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
    209 	{
    210 		shader.str("");
    211 		shader
    212 			<< getVersionAndExtension(ctx)
    213 			<< "layout (triangles) in; \n"
    214 			<< "layout (triangle_strip, max_vertices = 32) out; \n"
    215 			<< "void main () \n"
    216 			<< "{ \n"
    217 			<<		testConfigs[idx].varyingCheck
    218 			<< "} \n";
    219 
    220 		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside geometry shader");
    221 		verifyShader(ctx, glu::SHADERTYPE_GEOMETRY, shader.str(), EXPECT_RESULT_FAIL);
    222 		ctx.endSection();
    223 	}
    224 }
    225 
    226 void index_outside_sample_mask_range (NegativeTestContext& ctx)
    227 {
    228 	checkSupported(ctx);
    229 
    230 	std::ostringstream	shader;
    231 	const int			MAX_TYPES	= 2;
    232 	const int			MAX_INDEXES = 2;
    233 
    234 	struct testConfig
    235 	{
    236 		std::string builtInType[MAX_TYPES];
    237 		std::string invalidIndex[MAX_INDEXES];
    238 	} testConfigs =
    239 	{
    240 		{
    241 			"gl_SampleMask",
    242 			"gl_SampleMaskIn"
    243 		},
    244 		{
    245 			"	const highp int invalidIndex = (gl_MaxSamples + 31) / 32; \n",
    246 			"	const highp int invalidIndex = -1; \n"
    247 		}
    248 	};
    249 
    250 	for (int typeIdx = 0; typeIdx < MAX_TYPES; typeIdx++)
    251 	{
    252 		for (int invalidIdx = 0; invalidIdx < MAX_INDEXES; invalidIdx++)
    253 		{
    254 			shader.str("");
    255 			shader
    256 				<< getVersionAndExtension(ctx)
    257 				<< "layout (location = 0) out mediump vec4 fs_color; \n"
    258 				<< "void main() \n"
    259 				<< "{ \n"
    260 				<<		testConfigs.invalidIndex[invalidIdx]
    261 				<< "	highp int invalidValue = " << testConfigs.builtInType[typeIdx] << "[invalidIndex]; \n"
    262 				<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
    263 				<< "} \n";
    264 
    265 			ctx.beginSection("OES_sample_variables: using constant integral expression outside of " + testConfigs.builtInType[typeIdx] + " bounds");
    266 			verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
    267 			ctx.endSection();
    268 		}
    269 	}
    270 }
    271 
    272 void access_built_in_types_without_extension (NegativeTestContext& ctx)
    273 {
    274 	checkSupported(ctx);
    275 
    276 	std::ostringstream	shader;
    277 
    278 	struct testConfig
    279 	{
    280 		std::string builtInType;
    281 		std::string varyingCheck;
    282 	} testConfigs[] =
    283 	{
    284 		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
    285 		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
    286 		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"},
    287 		{"gl_SampleMask",		"	highp int readValue = gl_SampleMask[0]; \n"},
    288 	};
    289 
    290 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
    291 	{
    292 		shader.str("");
    293 		shader
    294 			<< "#version 310 es \n"
    295 			<< "layout (location = 0) out mediump vec4 fs_color; \n"
    296 			<< "void main() \n"
    297 			<< "{ \n"
    298 			<<		testConfigs[idx].varyingCheck
    299 			<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
    300 			<< "} \n";
    301 
    302 		ctx.beginSection("OES_sample_variables: accessing built-in type " + testConfigs[idx].builtInType + " in shader version 310 ES without required extension");
    303 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
    304 		ctx.endSection();
    305 	}
    306 }
    307 
    308 void redeclare_built_in_types (NegativeTestContext& ctx)
    309 {
    310 	checkSupported(ctx);
    311 
    312 	std::ostringstream	shader;
    313 	std::ostringstream	testName;
    314 
    315 	const char* const testConfigs[] =
    316 	{
    317 		"gl_SampleID",
    318 		"gl_SamplePosition",
    319 		"gl_SampleMaskIn",
    320 		"gl_SampleMask",
    321 	};
    322 
    323 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
    324 	{
    325 		shader.str("");
    326 		shader
    327 			<< getVersionAndExtension(ctx)
    328 			<< "layout (location = 0) out mediump vec4 fs_color; \n"
    329 			<< "uniform lowp int " << testConfigs[idx] << "; \n"
    330 			<< "void main() \n"
    331 			<< "{ \n"
    332 			<< "	if (" << testConfigs[idx] << " == 0) \n"
    333 			<< "		fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
    334 			<< "	else \n"
    335 			<< "		fs_color = vec4(0.0f, 1.0f, 0.0f, 1.0f); \n"
    336 			<< "} \n";
    337 
    338 		testName.str("");
    339 		testName << "OES_sample_variables: redeclare built-in type " << testConfigs[idx];
    340 		ctx.beginSection(testName.str());
    341 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
    342 		ctx.endSection();
    343 	}
    344 }
    345 
    346 } // anonymous
    347 
    348 std::vector<FunctionContainer> getNegativeSampleVariablesTestFunctions (void)
    349 {
    350 	const FunctionContainer funcs[] =
    351 	{
    352 		{write_to_read_only_types,						"write_to_read_only_types",						"tests trying writing to read-only built-in sample variables"},
    353 		{access_built_in_types_inside_other_shaders,	"access_built_in_types_inside_other_shaders",	"Tests try to access fragment shader sample variables in other shaders"},
    354 		{index_outside_sample_mask_range,				"index_outside_sample_mask_range",				"tests try to index into built-in sample array types out of bounds"},
    355 		{access_built_in_types_without_extension,		"access_built_in_types_without_extension",		"tests try to access built-in sample types without the correct extension using version 310 es"},
    356 		{redeclare_built_in_types,						"redeclare_built_in_types",						"Tests try to redeclare built-in sample types"},
    357 	};
    358 
    359 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
    360 }
    361 
    362 } // NegativeTestShared
    363 } // Functional
    364 } // gles31
    365 } // deqp
    366