• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 Storage Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fNegativeShaderStorageTests.hpp"
25 
26 #include "gluShaderProgram.hpp"
27 #include "glwDefs.hpp"
28 #include "glwEnums.hpp"
29 
30 namespace deqp
31 {
32 namespace gles31
33 {
34 namespace Functional
35 {
36 namespace NegativeTestShared
37 {
38 namespace
39 {
40 
verifyProgram(NegativeTestContext & ctx,glu::ProgramSources sources)41 void verifyProgram(NegativeTestContext& ctx, glu::ProgramSources sources)
42 {
43 	tcu::TestLog&				log			= ctx.getLog();
44 	const glu::ShaderProgram	program		(ctx.getRenderContext(), sources);
45 	bool						testFailed	= false;
46 
47 	log << program;
48 
49 	testFailed = program.getProgramInfo().linkOk;
50 
51 	if (testFailed)
52 	{
53 		const char* const message("Program was not expected to link.");
54 		log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
55 		ctx.fail(message);
56 	}
57 }
58 
getShaderExtensionDeclaration(glw::GLenum glShaderType)59 const char* getShaderExtensionDeclaration (glw::GLenum glShaderType)
60 {
61 	switch (glShaderType)
62 	{
63 		case GL_TESS_CONTROL_SHADER:
64 		case GL_TESS_EVALUATION_SHADER: return "#extension GL_EXT_tessellation_shader : require\n";
65 		case GL_GEOMETRY_SHADER:		return "#extension GL_EXT_geometry_shader : require\n";
66 		default:
67 			return "";
68 	}
69 }
70 
getGLUShaderType(glw::GLenum glShaderType)71 glu::ShaderType getGLUShaderType (glw::GLenum glShaderType)
72 {
73 	switch (glShaderType)
74 	{
75 		case GL_VERTEX_SHADER:			 return glu::SHADERTYPE_VERTEX;
76 		case GL_FRAGMENT_SHADER:		 return glu::SHADERTYPE_FRAGMENT;
77 		case GL_TESS_CONTROL_SHADER:	 return glu::SHADERTYPE_TESSELLATION_CONTROL;
78 		case GL_TESS_EVALUATION_SHADER:	 return glu::SHADERTYPE_TESSELLATION_EVALUATION;
79 		case GL_GEOMETRY_SHADER:		 return glu::SHADERTYPE_GEOMETRY;
80 		case GL_COMPUTE_SHADER:			 return glu::SHADERTYPE_COMPUTE;
81 		default:
82 			DE_FATAL("Unknown shader type");
83 			return glu::SHADERTYPE_LAST;
84 	}
85 }
86 
getMaxSSBlockSizeEnum(glw::GLenum glShaderType)87 glw::GLenum getMaxSSBlockSizeEnum (glw::GLenum glShaderType)
88 {
89 	switch (glShaderType)
90 	{
91 		case GL_VERTEX_SHADER:			 return GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
92 		case GL_FRAGMENT_SHADER:		 return GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
93 		case GL_TESS_CONTROL_SHADER:	 return GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
94 		case GL_TESS_EVALUATION_SHADER:	 return GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
95 		case GL_GEOMETRY_SHADER:		 return GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
96 		case GL_COMPUTE_SHADER:			 return GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
97 		default:
98 			 DE_FATAL("Unknown shader type");
99 			 return -1;
100 	}
101 }
102 
getMaxSSBlockSize(NegativeTestContext & ctx,glw::GLenum glShaderType)103 int getMaxSSBlockSize (NegativeTestContext& ctx, glw::GLenum glShaderType)
104 {
105 	int maxSSBlocks = 0;
106 	ctx.glGetIntegerv(getMaxSSBlockSizeEnum(glShaderType), &maxSSBlocks);
107 
108 	return maxSSBlocks;
109 }
110 
genBlockSource(NegativeTestContext & ctx,deInt64 numSSBlocks,glw::GLenum shaderType)111 std::string genBlockSource (NegativeTestContext& ctx, deInt64 numSSBlocks, glw::GLenum shaderType)
112 {
113 	const bool				isES32		= contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
114 	const glu::GLSLVersion	version		= isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
115 	std::ostringstream		source;
116 
117 	source	<< glu::getGLSLVersionDeclaration(version) << "\n"
118 			<< ((isES32) ? "" : getShaderExtensionDeclaration(shaderType));
119 
120 	switch (shaderType)
121 	{
122 		case GL_VERTEX_SHADER:
123 		case GL_FRAGMENT_SHADER:
124 			break;
125 
126 		case GL_COMPUTE_SHADER:
127 			source << "layout (local_size_x = 1) in;\n";
128 			break;
129 
130 		case GL_GEOMETRY_SHADER:
131 			source << "layout(points) in;\n"
132 				   << "layout(line_strip, max_vertices = 3) out;\n";
133 			break;
134 
135 		case GL_TESS_CONTROL_SHADER:
136 			source << "layout(vertices = 10) out;\n";
137 			break;
138 
139 		case GL_TESS_EVALUATION_SHADER:
140 			source << "layout(triangles) in;\n";
141 			break;
142 
143 		default:
144 			DE_FATAL("Unknown shader type");
145 			break;
146 	}
147 
148 	source  << "\n"
149 			<< "layout(std430, binding = 0) buffer Block {\n"
150 			<< "    int value;\n"
151 			<< "} sb_in[" << numSSBlocks << "];\n"
152 			<< "void main(void) { sb_in[0].value = 1; }\n";
153 
154 	return source.str();
155 }
156 
genCommonSource(NegativeTestContext & ctx,glw::GLenum shaderType)157 std::string genCommonSource (NegativeTestContext& ctx, glw::GLenum shaderType)
158 {
159 	const bool				isES32		= contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
160 	const glu::GLSLVersion	version		= isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
161 	std::ostringstream		source;
162 
163 	source << glu::getGLSLVersionDeclaration(version) << "\n"
164 		   << ((isES32) ? "" : getShaderExtensionDeclaration(shaderType));
165 
166 	switch (shaderType)
167 	{
168 		case GL_TESS_CONTROL_SHADER:
169 			source	<< "layout(vertices = 3) out;\n"
170 					<< "void main() {}\n";
171 			break;
172 
173 		case GL_TESS_EVALUATION_SHADER:
174 			source	<< "layout(triangles, equal_spacing, cw) in;\n"
175 					<< "void main() {}\n";
176 			break;
177 
178 		default:
179 			source  << "void main() {}\n";
180 			break;
181 	}
182 
183 	return source.str();
184 }
185 
genMaxSSBlocksSource(NegativeTestContext & ctx,glw::GLenum glShaderType,glu::ProgramSources & sources)186 int genMaxSSBlocksSource (NegativeTestContext& ctx, glw::GLenum glShaderType, glu::ProgramSources& sources)
187 {
188 	int		maxSSBlocks				= getMaxSSBlockSize(ctx, glShaderType);
189 	const	std::string shaderSrc	= genBlockSource(ctx, (maxSSBlocks), glShaderType);
190 
191 	sources.sources[getGLUShaderType(glShaderType)].push_back(shaderSrc);
192 
193 	return maxSSBlocks;
194 }
195 
block_number_limits(NegativeTestContext & ctx)196 void block_number_limits (NegativeTestContext& ctx)
197 {
198 	const glw::GLenum glShaderTypes[] =
199 	{
200 		GL_VERTEX_SHADER,
201 		GL_FRAGMENT_SHADER,
202 		GL_TESS_CONTROL_SHADER,
203 		GL_TESS_EVALUATION_SHADER,
204 		GL_GEOMETRY_SHADER,
205 		GL_COMPUTE_SHADER,
206 	};
207 
208 	const std::string	vertSource			= genCommonSource(ctx, GL_VERTEX_SHADER);
209 	const std::string	fragSource			= genCommonSource(ctx, GL_FRAGMENT_SHADER);
210 	const std::string	tessControlSource	= genCommonSource(ctx, GL_TESS_CONTROL_SHADER);
211 	const std::string	tessEvalSource		= genCommonSource(ctx, GL_TESS_EVALUATION_SHADER);
212 
213 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(glShaderTypes); ndx++)
214 	{
215 		ctx.beginSection("maxShaderStorageBlocks: Exceed limits");
216 
217 		if (!ctx.isShaderSupported(static_cast<glu::ShaderType>(getGLUShaderType(glShaderTypes[ndx]))))
218 		{
219 			ctx.endSection();
220 			continue;
221 		}
222 
223 		int					maxSSBlocks			= getMaxSSBlockSize(ctx, glShaderTypes[ndx]);
224 		std::string			source				= genBlockSource(ctx, maxSSBlocks+1, glShaderTypes[ndx]);
225 
226 		glu::ProgramSources sources;
227 
228 		if (maxSSBlocks == 0)
229 		{
230 			ctx.endSection();
231 			continue;
232 		}
233 
234 		switch (glShaderTypes[ndx])
235 		{
236 			case GL_VERTEX_SHADER:
237 				sources << glu::VertexSource(source)
238 						<< glu::FragmentSource(fragSource);
239 				break;
240 
241 			case GL_FRAGMENT_SHADER:
242 				sources << glu::VertexSource(vertSource)
243 						<< glu::FragmentSource(source);
244 				break;
245 
246 			case GL_TESS_CONTROL_SHADER:
247 				sources << glu::VertexSource(vertSource)
248 						<< glu::FragmentSource(fragSource)
249 						<< glu::TessellationControlSource(source)
250 						<< glu::TessellationEvaluationSource(tessEvalSource);
251 				break;
252 
253 			case GL_TESS_EVALUATION_SHADER:
254 				sources << glu::VertexSource(vertSource)
255 						<< glu::FragmentSource(fragSource)
256 						<< glu::TessellationControlSource(tessControlSource)
257 						<< glu::TessellationEvaluationSource(source);
258 				break;
259 
260 			case GL_GEOMETRY_SHADER:
261 				sources << glu::VertexSource(vertSource)
262 						<< glu::FragmentSource(fragSource)
263 						<< glu::GeometrySource(source);
264 				break;
265 
266 			case GL_COMPUTE_SHADER:
267 				sources << glu::ComputeSource(source);
268 				break;
269 
270 			default:
271 				DE_FATAL("Unknown shader type");
272 				break;
273 		}
274 
275 		verifyProgram(ctx, sources);
276 		ctx.endSection();
277 	}
278 }
279 
max_combined_block_number_limit(NegativeTestContext & ctx)280 void max_combined_block_number_limit (NegativeTestContext& ctx)
281 {
282 	ctx.beginSection("maxCombinedShaderStorageBlocks: Exceed limits");
283 
284 	glu::ProgramSources sources;
285 
286 	int combinedSSBlocks	= 0;
287 	int maxCombinedSSBlocks = 0;
288 
289 	combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_VERTEX_SHADER, sources);
290 	combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_FRAGMENT_SHADER, sources);
291 
292 	if ((ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_CONTROL)) && (ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_EVALUATION)))
293 	{
294 		combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_TESS_CONTROL_SHADER, sources);
295 		combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_TESS_EVALUATION_SHADER, sources);
296 	}
297 
298 	if (ctx.isShaderSupported(glu::SHADERTYPE_GEOMETRY))
299 		combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_GEOMETRY_SHADER, sources);
300 
301 	ctx.glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedSSBlocks);
302 
303 	ctx.getLog() << tcu::TestLog::Message << "GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: " << maxCombinedSSBlocks << tcu::TestLog::EndMessage;
304 	ctx.getLog() << tcu::TestLog::Message << "Combined shader storage blocks: " << combinedSSBlocks << tcu::TestLog::EndMessage;
305 
306 	if (combinedSSBlocks > maxCombinedSSBlocks)
307 		verifyProgram(ctx, sources);
308 	else
309 		ctx.getLog() << tcu::TestLog::Message << "Test skipped: Combined shader storage blocks < GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: " << tcu::TestLog::EndMessage;
310 
311 	ctx.endSection();
312 }
313 
314 } // anonymous
315 
getNegativeShaderStorageTestFunctions()316 std::vector<FunctionContainer> getNegativeShaderStorageTestFunctions ()
317 {
318 	const FunctionContainer funcs[] =
319 	{
320 		{ block_number_limits,				"block_number_limits",				"Invalid shader linkage" },
321 		{ max_combined_block_number_limit,	"max_combined_block_number_limit",	"Invalid shader linkage" },
322 	};
323 
324 	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
325 }
326 
327 } // NegativeTestShared
328 } // Functional
329 } // gles31
330 } // deqp
331