Merge Vulkan CTS 1.0.2.2 into goog/oc-dev
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fNegativeShaderStorageTests.cpp
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
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
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
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
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
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
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
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
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
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
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
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