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