• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
verifyShader(NegativeTestContext & ctx,glu::ShaderType shaderType,std::string shaderSource,ExpectResult expect)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 
getVersionAndExtension(NegativeTestContext & ctx)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 
checkSupported(NegativeTestContext & ctx)93 void checkSupported (NegativeTestContext& ctx)
94 {
95 	const bool isES32orGL45 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
96 							  contextSupports(ctx.getRenderContext().getType(), glu::ApiType::core(4, 5));
97 
98 	if (!isES32orGL45 && !ctx.isExtensionSupported("GL_OES_sample_variables"))
99 		TCU_THROW(NotSupportedError, "GL_OES_sample_variables is not supported.");
100 }
101 
write_to_read_only_types(NegativeTestContext & ctx)102 void write_to_read_only_types (NegativeTestContext& ctx)
103 {
104 	checkSupported(ctx);
105 
106 	std::ostringstream	shader;
107 
108 	struct testConfig
109 	{
110 		std::string builtInType;
111 		std::string varyingCheck;
112 	} testConfigs[] =
113 	{
114 		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
115 		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
116 		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"}
117 	};
118 
119 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
120 	{
121 		shader.str("");
122 		shader
123 			<< getVersionAndExtension(ctx)
124 			<< "layout (location = 0) out mediump vec4 fs_color; \n"
125 			<< "void main() \n"
126 			<< "{ \n"
127 			<<		testConfigs[idx].varyingCheck
128 			<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
129 			<< "} \n";
130 
131 		ctx.beginSection("OES_sample_variables: trying to write to built-in read-only variable" + testConfigs[idx].builtInType);
132 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
133 		ctx.endSection();
134 	}
135 }
136 
access_built_in_types_inside_other_shaders(NegativeTestContext & ctx)137 void access_built_in_types_inside_other_shaders (NegativeTestContext& ctx)
138 {
139 	checkSupported(ctx);
140 
141 	if (glu::isContextTypeES(ctx.getRenderContext().getType()))
142 	{
143 		if ((!ctx.isExtensionSupported("GL_EXT_tessellation_shader") && !ctx.isExtensionSupported("GL_OES_tessellation_shader")) ||
144 			(!ctx.isExtensionSupported("GL_EXT_geometry_shader") && !ctx.isExtensionSupported("GL_OES_geometry_shader")))
145 			TCU_THROW(NotSupportedError, "tessellation and geometry shader extensions not supported");
146 	}
147 
148 	std::ostringstream	shader;
149 
150 	struct testConfig
151 	{
152 		std::string builtInType;
153 		std::string varyingCheck;
154 	} testConfigs[] =
155 	{
156 		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
157 		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
158 		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"},
159 		{"gl_SampleMask",		"	highp int readValue = gl_SampleMask[0]; \n"},
160 	};
161 
162 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
163 	{
164 		shader.str("");
165 		shader
166 			<< getVersionAndExtension(ctx)
167 			<< "void main () \n"
168 			<< "{ \n"
169 			<<		testConfigs[idx].varyingCheck
170 			<< "	gl_Position = vec4(1.0f, 0.0f, 0.0f , 1.0f); \n"
171 			<< "} \n";
172 
173 		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside vertex shader");
174 		verifyShader(ctx, glu::SHADERTYPE_VERTEX, shader.str(), EXPECT_RESULT_FAIL);
175 		ctx.endSection();
176 	}
177 
178 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
179 	{
180 		shader.str("");
181 		shader
182 			<< getVersionAndExtension(ctx)
183 			<< "layout (vertices = 3) out; \n"
184 			<< "void main () \n"
185 			<< "{ \n"
186 			<<		testConfigs[idx].varyingCheck
187 			<< "} \n";
188 
189 		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside tessellation control shader");
190 		verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, shader.str(), EXPECT_RESULT_FAIL);
191 		ctx.endSection();
192 	}
193 
194 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
195 	{
196 		shader.str("");
197 		shader
198 			<< getVersionAndExtension(ctx)
199 			<< "layout (triangles, equal_spacing, ccw) in; \n"
200 			<< "void main () \n"
201 			<< "{ \n"
202 			<<		testConfigs[idx].varyingCheck
203 			<< "} \n";
204 
205 		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside tessellation evaluation shader");
206 		verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_EVALUATION, shader.str(), EXPECT_RESULT_FAIL);
207 		ctx.endSection();
208 	}
209 
210 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
211 	{
212 		shader.str("");
213 		shader
214 			<< getVersionAndExtension(ctx)
215 			<< "layout (triangles) in; \n"
216 			<< "layout (triangle_strip, max_vertices = 32) out; \n"
217 			<< "void main () \n"
218 			<< "{ \n"
219 			<<		testConfigs[idx].varyingCheck
220 			<< "} \n";
221 
222 		ctx.beginSection("OES_sample_variables: trying to use fragment shader built-in sampler variable " + testConfigs[idx].builtInType + " inside geometry shader");
223 		verifyShader(ctx, glu::SHADERTYPE_GEOMETRY, shader.str(), EXPECT_RESULT_FAIL);
224 		ctx.endSection();
225 	}
226 }
227 
index_outside_sample_mask_range(NegativeTestContext & ctx)228 void index_outside_sample_mask_range (NegativeTestContext& ctx)
229 {
230 	// Skip this test for GL4.5 - shader will compile
231 	if (!glu::isContextTypeES(ctx.getRenderContext().getType()))
232 		return;
233 
234 	checkSupported(ctx);
235 
236 	std::ostringstream	shader;
237 	const int			MAX_TYPES	= 2;
238 	const int			MAX_INDEXES = 2;
239 
240 	struct testConfig
241 	{
242 		std::string builtInType[MAX_TYPES];
243 		std::string invalidIndex[MAX_INDEXES];
244 	} testConfigs =
245 	{
246 		{
247 			"gl_SampleMask",
248 			"gl_SampleMaskIn"
249 		},
250 		{
251 			"	const highp int invalidIndex = (gl_MaxSamples + 31) / 32; \n",
252 			"	const highp int invalidIndex = -1; \n"
253 		}
254 	};
255 
256 	for (int typeIdx = 0; typeIdx < MAX_TYPES; typeIdx++)
257 	{
258 		for (int invalidIdx = 0; invalidIdx < MAX_INDEXES; invalidIdx++)
259 		{
260 			shader.str("");
261 			shader
262 				<< getVersionAndExtension(ctx)
263 				<< "layout (location = 0) out mediump vec4 fs_color; \n"
264 				<< "void main() \n"
265 				<< "{ \n"
266 				<<		testConfigs.invalidIndex[invalidIdx]
267 				<< "	highp int invalidValue = " << testConfigs.builtInType[typeIdx] << "[invalidIndex]; \n"
268 				<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
269 				<< "} \n";
270 
271 			ctx.beginSection("OES_sample_variables: using constant integral expression outside of " + testConfigs.builtInType[typeIdx] + " bounds");
272 			verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
273 			ctx.endSection();
274 		}
275 	}
276 }
277 
access_built_in_types_without_extension(NegativeTestContext & ctx)278 void access_built_in_types_without_extension (NegativeTestContext& ctx)
279 {
280 	checkSupported(ctx);
281 
282 	std::ostringstream	shader;
283 
284 	struct testConfig
285 	{
286 		std::string builtInType;
287 		std::string varyingCheck;
288 	} testConfigs[] =
289 	{
290 		{"gl_SampleID",			"	lowp int writeValue = 1; \n	gl_SampleID = writeValue; \n"},
291 		{"gl_SamplePosition",	"	mediump vec2 writeValue = vec2(1.0f, 1.0f); \n	gl_SamplePosition = writeValue; \n"},
292 		{"gl_SampleMaskIn",		"	lowp int writeValue = 1; \n	gl_SampleMaskIn[0] = writeValue; \n"},
293 		{"gl_SampleMask",		"	highp int readValue = gl_SampleMask[0]; \n"},
294 	};
295 
296 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
297 	{
298 		shader.str("");
299 		shader
300 			<< "#version 310 es \n"
301 			<< "layout (location = 0) out mediump vec4 fs_color; \n"
302 			<< "void main() \n"
303 			<< "{ \n"
304 			<<		testConfigs[idx].varyingCheck
305 			<< "	fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
306 			<< "} \n";
307 
308 		ctx.beginSection("OES_sample_variables: accessing built-in type " + testConfigs[idx].builtInType + " in shader version 310 ES without required extension");
309 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
310 		ctx.endSection();
311 	}
312 }
313 
redeclare_built_in_types(NegativeTestContext & ctx)314 void redeclare_built_in_types (NegativeTestContext& ctx)
315 {
316 	// skip this test for core GL
317 	if (glu::isContextTypeGLCore(ctx.getRenderContext().getType()))
318 		return;
319 
320 	checkSupported(ctx);
321 
322 	std::ostringstream	shader;
323 	std::ostringstream	testName;
324 
325 	const char* const testConfigs[] =
326 	{
327 		"gl_SampleID",
328 		"gl_SamplePosition",
329 		"gl_SampleMaskIn",
330 		"gl_SampleMask",
331 	};
332 
333 	for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(testConfigs); idx++)
334 	{
335 		shader.str("");
336 		shader
337 			<< getVersionAndExtension(ctx)
338 			<< "layout (location = 0) out mediump vec4 fs_color; \n"
339 			<< "uniform lowp int " << testConfigs[idx] << "; \n"
340 			<< "void main() \n"
341 			<< "{ \n"
342 			<< "	if (" << testConfigs[idx] << " == 0) \n"
343 			<< "		fs_color = vec4(1.0f, 0.0f, 0.0f, 1.0f); \n"
344 			<< "	else \n"
345 			<< "		fs_color = vec4(0.0f, 1.0f, 0.0f, 1.0f); \n"
346 			<< "} \n";
347 
348 		testName.str("");
349 		testName << "OES_sample_variables: redeclare built-in type " << testConfigs[idx];
350 		ctx.beginSection(testName.str());
351 		verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, shader.str(), EXPECT_RESULT_FAIL);
352 		ctx.endSection();
353 	}
354 }
355 
356 } // anonymous
357 
getNegativeSampleVariablesTestFunctions(void)358 std::vector<FunctionContainer> getNegativeSampleVariablesTestFunctions (void)
359 {
360 	const FunctionContainer funcs[] =
361 	{
362 		{write_to_read_only_types,						"write_to_read_only_types",						"tests trying writing to read-only built-in sample variables"},
363 		{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"},
364 		{index_outside_sample_mask_range,				"index_outside_sample_mask_range",				"tests try to index into built-in sample array types out of bounds"},
365 		{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"},
366 		{redeclare_built_in_types,						"redeclare_built_in_types",						"Tests try to redeclare built-in sample types"},
367 	};
368 
369 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
370 }
371 
372 } // NegativeTestShared
373 } // Functional
374 } // gles31
375 } // deqp
376