Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / modules / gles31 / functional / es31fShaderStateQueryTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 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 Shader state query tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "es31fShaderStateQueryTests.hpp"
25 #include "es31fInfoLogQueryShared.hpp"
26 #include "glsStateQueryUtil.hpp"
27 #include "tcuTestLog.hpp"
28 #include "tcuStringTemplate.hpp"
29 #include "gluShaderProgram.hpp"
30 #include "gluRenderContext.hpp"
31 #include "gluCallLogWrapper.hpp"
32 #include "gluContextInfo.hpp"
33 #include "gluStrUtil.hpp"
34 #include "glwFunctions.hpp"
35 #include "glwEnums.hpp"
36
37 namespace deqp
38 {
39 namespace gles31
40 {
41 namespace Functional
42 {
43 namespace
44 {
45
46 static inline std::string brokenShaderSource (const glu::ContextType &contextType)
47 {
48         const std::string glslVersionDecl = glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(contextType));
49
50         return  glslVersionDecl + "\n"
51                         "broken, this should not compile,\n"
52                         "{";
53 }
54
55 class BaseTypeCase : public TestCase
56 {
57 public:
58         struct TestTypeInfo
59         {
60                 glw::GLenum     glType;
61                 const char*     declarationStr;
62                 const char*     accessStr;
63         };
64
65                                                                                 BaseTypeCase            (Context& ctx, const char* name, const char* desc, const char* extension);
66
67 private:
68         IterateResult                                           iterate                         (void);
69         virtual std::vector<TestTypeInfo>       getInfos                        (void) const = 0;
70         virtual void                                            checkRequirements       (void) const;
71
72         const char* const                                       m_extension;
73 };
74
75 BaseTypeCase::BaseTypeCase (Context& ctx, const char* name, const char* desc, const char* extension)
76         : TestCase              (ctx, name, desc)
77         , m_extension   (extension)
78 {
79 }
80
81 BaseTypeCase::IterateResult BaseTypeCase::iterate (void)
82 {
83         static const char* const        vertexSourceTemplate    =       "${VERSIONDECL}\n"
84                                                                                                                         "in highp vec4 a_position;\n"
85                                                                                                                         "void main(void)\n"
86                                                                                                                         "{\n"
87                                                                                                                         "       gl_Position = a_position;\n"
88                                                                                                                         "}\n";
89         static const char* const        fragmentSourceTemplate  =       "${VERSIONDECL}\n"
90                                                                                                                         "${EXTENSIONSTATEMENT}"
91                                                                                                                         "${DECLARATIONSTR};\n"
92                                                                                                                         "layout(location = 0) out highp vec4 dEQP_FragColor;\n"
93                                                                                                                         "void main(void)\n"
94                                                                                                                         "{\n"
95                                                                                                                         "       dEQP_FragColor = vec4(${ACCESSSTR});\n"
96                                                                                                                         "}\n";
97
98         tcu::ResultCollector            result                  (m_testCtx.getLog());
99         std::vector<TestTypeInfo>       samplerTypes    = getInfos();
100         auto                                            ctxType                 = m_context.getRenderContext().getType();
101         const bool                                      isES32orGL45    = glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
102                                                                                                   glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
103
104         if (m_extension && !isES32orGL45 && !m_context.getContextInfo().isExtensionSupported(m_extension))
105                 throw tcu::NotSupportedError("Test requires " + std::string(m_extension));
106         checkRequirements();
107
108         for (int typeNdx = 0; typeNdx < (int)samplerTypes.size(); ++typeNdx)
109         {
110                 const tcu::ScopedLogSection                     section (m_testCtx.getLog(),
111                                                                                                          std::string(glu::getShaderVarTypeStr(samplerTypes[typeNdx].glType).toString()),
112                                                                                                          "Uniform type " + glu::getShaderVarTypeStr(samplerTypes[typeNdx].glType).toString());
113
114                 std::map<std::string, std::string>      shaderArgs;
115                 shaderArgs["DECLARATIONSTR"]            = samplerTypes[typeNdx].declarationStr;
116                 shaderArgs["ACCESSSTR"]                         = samplerTypes[typeNdx].accessStr;
117                 shaderArgs["EXTENSIONSTATEMENT"]        = (m_extension && !isES32orGL45) ? (std::string() + "#extension " + m_extension + " : require\n") : ("");
118                 shaderArgs["VERSIONDECL"]                       = glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(ctxType));
119
120                 const std::string                                       fragmentSource  = tcu::StringTemplate(fragmentSourceTemplate).specialize(shaderArgs);
121                 const std::string                                       vertexSource    = tcu::StringTemplate(vertexSourceTemplate).specialize(shaderArgs);
122                 const glw::Functions&                           gl                              = m_context.getRenderContext().getFunctions();
123                 glu::ShaderProgram                                      program                 (m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vertexSource) << glu::FragmentSource(fragmentSource));
124
125                 m_testCtx.getLog() << tcu::TestLog::Message << "Building program with uniform sampler of type " << glu::getShaderVarTypeStr(samplerTypes[typeNdx].glType) << tcu::TestLog::EndMessage;
126
127                 if (!program.isOk())
128                 {
129                         m_testCtx.getLog() << program;
130                         result.fail("could not build shader");
131                 }
132                 else
133                 {
134                         // only one uniform -- uniform at index 0
135                         int uniforms = 0;
136                         gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORMS, &uniforms);
137
138                         if (uniforms != 1)
139                                 result.fail("Unexpected GL_ACTIVE_UNIFORMS, expected 1");
140                         else
141                         {
142                                 // check type
143                                 const glw::GLuint       uniformIndex    = 0;
144                                 glw::GLint                      type                    = 0;
145
146                                 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying uniform type." << tcu::TestLog::EndMessage;
147                                 gl.getActiveUniformsiv(program.getProgram(), 1, &uniformIndex, GL_UNIFORM_TYPE, &type);
148
149                                 if (type != (glw::GLint)samplerTypes[typeNdx].glType)
150                                 {
151                                         std::ostringstream buf;
152                                         buf << "Invalid type, expected " << samplerTypes[typeNdx].glType << ", got " << type;
153                                         result.fail(buf.str());
154                                 }
155                         }
156                 }
157
158                 GLU_EXPECT_NO_ERROR(gl.getError(), "");
159         }
160
161         result.setTestContextResult(m_testCtx);
162         return STOP;
163 }
164
165 void BaseTypeCase::checkRequirements (void) const
166 {
167 }
168
169 class CoreSamplerTypeCase : public BaseTypeCase
170 {
171 public:
172                                                                 CoreSamplerTypeCase     (Context& ctx, const char* name, const char* desc);
173
174 private:
175         std::vector<TestTypeInfo>       getInfos                        (void) const;
176 };
177
178 CoreSamplerTypeCase::CoreSamplerTypeCase (Context& ctx, const char* name, const char* desc)
179         : BaseTypeCase(ctx, name, desc, DE_NULL)
180 {
181 }
182
183 std::vector<BaseTypeCase::TestTypeInfo> CoreSamplerTypeCase::getInfos (void) const
184 {
185         static const TestTypeInfo samplerTypes[] =
186         {
187                 { GL_SAMPLER_2D_MULTISAMPLE,                            "uniform highp sampler2DMS u_sampler",  "texelFetch(u_sampler, ivec2(gl_FragCoord.xy), 0)" },
188                 { GL_INT_SAMPLER_2D_MULTISAMPLE,                        "uniform highp isampler2DMS u_sampler", "texelFetch(u_sampler, ivec2(gl_FragCoord.xy), 0)" },
189                 { GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,       "uniform highp usampler2DMS u_sampler", "texelFetch(u_sampler, ivec2(gl_FragCoord.xy), 0)" },
190         };
191
192         std::vector<TestTypeInfo> infos;
193         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
194                 infos.push_back(samplerTypes[ndx]);
195
196         return infos;
197 }
198
199 class MSArraySamplerTypeCase : public BaseTypeCase
200 {
201 public:
202                                                                 MSArraySamplerTypeCase  (Context& ctx, const char* name, const char* desc);
203
204 private:
205         std::vector<TestTypeInfo>       getInfos                                (void) const;
206 };
207
208 MSArraySamplerTypeCase::MSArraySamplerTypeCase (Context& ctx, const char* name, const char* desc)
209         : BaseTypeCase(ctx, name, desc, "GL_OES_texture_storage_multisample_2d_array")
210 {
211 }
212
213 std::vector<BaseTypeCase::TestTypeInfo> MSArraySamplerTypeCase::getInfos (void) const
214 {
215         static const TestTypeInfo samplerTypes[] =
216         {
217                 { GL_SAMPLER_2D_MULTISAMPLE_ARRAY,                              "uniform highp sampler2DMSArray u_sampler",             "texelFetch(u_sampler, ivec3(gl_FragCoord.xyz), 0)" },
218                 { GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,                  "uniform highp isampler2DMSArray u_sampler",    "texelFetch(u_sampler, ivec3(gl_FragCoord.xyz), 0)" },
219                 { GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, "uniform highp usampler2DMSArray u_sampler",    "texelFetch(u_sampler, ivec3(gl_FragCoord.xyz), 0)" },
220         };
221
222         std::vector<TestTypeInfo> infos;
223         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
224                 infos.push_back(samplerTypes[ndx]);
225
226         return infos;
227 }
228
229 class TextureBufferSamplerTypeCase : public BaseTypeCase
230 {
231 public:
232                                                                 TextureBufferSamplerTypeCase    (Context& ctx, const char* name, const char* desc);
233
234 private:
235         std::vector<TestTypeInfo>       getInfos                                                (void) const;
236 };
237
238 TextureBufferSamplerTypeCase::TextureBufferSamplerTypeCase (Context& ctx, const char* name, const char* desc)
239         : BaseTypeCase(ctx, name, desc, "GL_EXT_texture_buffer")
240 {
241 }
242
243 std::vector<BaseTypeCase::TestTypeInfo> TextureBufferSamplerTypeCase::getInfos (void) const
244 {
245         static const TestTypeInfo samplerTypes[] =
246         {
247                 { GL_SAMPLER_BUFFER,                            "uniform highp samplerBuffer u_sampler",        "texelFetch(u_sampler, int(gl_FragCoord.x))" },
248                 { GL_INT_SAMPLER_BUFFER,                        "uniform highp isamplerBuffer u_sampler",       "texelFetch(u_sampler, int(gl_FragCoord.x))" },
249                 { GL_UNSIGNED_INT_SAMPLER_BUFFER,       "uniform highp usamplerBuffer u_sampler",       "texelFetch(u_sampler, int(gl_FragCoord.x))" },
250         };
251
252         std::vector<TestTypeInfo> infos;
253         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
254                 infos.push_back(samplerTypes[ndx]);
255
256         return infos;
257 }
258
259 class TextureBufferImageTypeCase : public BaseTypeCase
260 {
261 public:
262                                                                 TextureBufferImageTypeCase      (Context& ctx, const char* name, const char* desc);
263
264 private:
265         std::vector<TestTypeInfo>       getInfos                                        (void) const;
266         void                                            checkRequirements                       (void) const;
267 };
268
269 TextureBufferImageTypeCase::TextureBufferImageTypeCase (Context& ctx, const char* name, const char* desc)
270         : BaseTypeCase(ctx, name, desc, "GL_EXT_texture_buffer")
271 {
272 }
273
274 std::vector<BaseTypeCase::TestTypeInfo> TextureBufferImageTypeCase::getInfos (void) const
275 {
276         static const TestTypeInfo samplerTypes[] =
277         {
278                 { GL_IMAGE_BUFFER,                              "layout(binding=0, rgba8) readonly uniform highp imageBuffer u_image",  "imageLoad(u_image, int(gl_FragCoord.x))" },
279                 { GL_INT_IMAGE_BUFFER,                  "layout(binding=0, r32i) readonly uniform highp iimageBuffer u_image",  "imageLoad(u_image, int(gl_FragCoord.x))" },
280                 { GL_UNSIGNED_INT_IMAGE_BUFFER, "layout(binding=0, r32ui) readonly uniform highp uimageBuffer u_image", "imageLoad(u_image, int(gl_FragCoord.x))" },
281         };
282
283         std::vector<TestTypeInfo> infos;
284         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
285                 infos.push_back(samplerTypes[ndx]);
286
287         return infos;
288 }
289
290 void TextureBufferImageTypeCase::checkRequirements (void) const
291 {
292         if (m_context.getContextInfo().getInt(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) < 1)
293                 throw tcu::NotSupportedError("Test requires fragment images");
294 }
295
296 class CubeArraySamplerTypeCase : public BaseTypeCase
297 {
298 public:
299                                                                 CubeArraySamplerTypeCase        (Context& ctx, const char* name, const char* desc);
300
301 private:
302         std::vector<TestTypeInfo>       getInfos                                                (void) const;
303 };
304
305 CubeArraySamplerTypeCase::CubeArraySamplerTypeCase (Context& ctx, const char* name, const char* desc)
306         : BaseTypeCase(ctx, name, desc, "GL_EXT_texture_cube_map_array")
307 {
308 }
309
310 std::vector<BaseTypeCase::TestTypeInfo> CubeArraySamplerTypeCase::getInfos (void) const
311 {
312         static const TestTypeInfo samplerTypes[] =
313         {
314                 { GL_SAMPLER_CUBE_MAP_ARRAY,                            "uniform highp samplerCubeArray u_sampler",                     "texture(u_sampler, gl_FragCoord.xxyz)"                 },
315                 { GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW,                     "uniform highp samplerCubeArrayShadow u_sampler",       "texture(u_sampler, gl_FragCoord.xxyz, 0.5)"    },
316                 { GL_INT_SAMPLER_CUBE_MAP_ARRAY,                        "uniform highp isamplerCubeArray u_sampler",            "texture(u_sampler, gl_FragCoord.xxyz)"                 },
317                 { GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY,       "uniform highp usamplerCubeArray u_sampler",            "texture(u_sampler, gl_FragCoord.xxyz)"                 },
318         };
319
320         std::vector<TestTypeInfo> infos;
321         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
322                 infos.push_back(samplerTypes[ndx]);
323
324         return infos;
325 }
326
327 class CubeArrayImageTypeCase : public BaseTypeCase
328 {
329 public:
330                                                                 CubeArrayImageTypeCase  (Context& ctx, const char* name, const char* desc);
331
332 private:
333         std::vector<TestTypeInfo>       getInfos                                (void) const;
334         void                                            checkRequirements               (void) const;
335 };
336
337 CubeArrayImageTypeCase::CubeArrayImageTypeCase (Context& ctx, const char* name, const char* desc)
338         : BaseTypeCase(ctx, name, desc, "GL_EXT_texture_cube_map_array")
339 {
340 }
341
342 std::vector<BaseTypeCase::TestTypeInfo> CubeArrayImageTypeCase::getInfos (void) const
343 {
344         static const TestTypeInfo samplerTypes[] =
345         {
346                 { GL_IMAGE_CUBE_MAP_ARRAY,                              "layout(binding=0, rgba8) readonly uniform highp imageCubeArray u_image",       "imageLoad(u_image, ivec3(gl_FragCoord.xyx))"   },
347                 { GL_INT_IMAGE_CUBE_MAP_ARRAY,                  "layout(binding=0, r32i) readonly uniform highp iimageCubeArray u_image",       "imageLoad(u_image, ivec3(gl_FragCoord.xyx))"   },
348                 { GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY, "layout(binding=0, r32ui) readonly uniform highp uimageCubeArray u_image",      "imageLoad(u_image, ivec3(gl_FragCoord.xyx))"   },
349         };
350
351         std::vector<TestTypeInfo> infos;
352         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
353                 infos.push_back(samplerTypes[ndx]);
354
355         return infos;
356 }
357
358 void CubeArrayImageTypeCase::checkRequirements (void) const
359 {
360         if (m_context.getContextInfo().getInt(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) < 1)
361                 throw tcu::NotSupportedError("Test requires fragment images");
362 }
363
364 class ShaderLogCase : public TestCase
365 {
366 public:
367                                                         ShaderLogCase   (Context& ctx, const char* name, const char* desc, glu::ShaderType shaderType);
368
369 private:
370         void                                    init                    (void);
371         IterateResult                   iterate                 (void);
372
373         const glu::ShaderType   m_shaderType;
374 };
375
376 ShaderLogCase::ShaderLogCase (Context& ctx, const char* name, const char* desc, glu::ShaderType shaderType)
377         : TestCase              (ctx, name, desc)
378         , m_shaderType  (shaderType)
379 {
380 }
381
382 void ShaderLogCase::init (void)
383 {
384         auto            ctxType                 = m_context.getRenderContext().getType();
385         const bool      isES32orGL45    = glu::contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
386                                                                   glu::contextSupports(ctxType, glu::ApiType::core(4, 5));
387
388         switch (m_shaderType)
389         {
390                 case glu::SHADERTYPE_VERTEX:
391                 case glu::SHADERTYPE_FRAGMENT:
392                 case glu::SHADERTYPE_COMPUTE:
393                         break;
394
395                 case glu::SHADERTYPE_GEOMETRY:
396                         if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader") && !isES32orGL45)
397                                 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension or an OpenGL ES 3.2 or higher context.");
398                         break;
399
400                 case glu::SHADERTYPE_TESSELLATION_CONTROL:
401                 case glu::SHADERTYPE_TESSELLATION_EVALUATION:
402                         if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader") && !isES32orGL45)
403                                 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension or an OpenGL ES 3.2 or higher context.");
404                         break;
405
406                 default:
407                         DE_ASSERT(false);
408                         break;
409         }
410 }
411
412 ShaderLogCase::IterateResult ShaderLogCase::iterate (void)
413 {
414         using gls::StateQueryUtil::StateQueryMemoryWriteGuard;
415
416         tcu::ResultCollector                                    result                  (m_testCtx.getLog());
417         glu::CallLogWrapper                                             gl                              (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
418         deUint32                                                                shader                  = 0;
419         const std::string                                               source                  = brokenShaderSource(m_context.getRenderContext().getType());
420         const char* const                                               brokenSource    = source.c_str();
421         StateQueryMemoryWriteGuard<glw::GLint>  logLen;
422
423         gl.enableLogging(true);
424
425         m_testCtx.getLog() << tcu::TestLog::Message << "Trying to compile broken shader source." << tcu::TestLog::EndMessage;
426
427         shader = gl.glCreateShader(glu::getGLShaderType(m_shaderType));
428         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "create shader");
429
430         gl.glShaderSource(shader, 1, &brokenSource, DE_NULL);
431         gl.glCompileShader(shader);
432         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "compile");
433
434         gl.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLen);
435         logLen.verifyValidity(result);
436
437         if (!logLen.isUndefined())
438                 verifyInfoLogQuery(result, gl, logLen, shader, &glu::CallLogWrapper::glGetShaderInfoLog, "glGetShaderInfoLog");
439
440         gl.glDeleteShader(shader);
441         GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "delete");
442
443         result.setTestContextResult(m_testCtx);
444         return STOP;
445 }
446
447 } // anonymous
448
449 ShaderStateQueryTests::ShaderStateQueryTests (Context& context)
450         : TestCaseGroup(context, "shader", "Shader state query tests")
451 {
452 }
453
454 ShaderStateQueryTests::~ShaderStateQueryTests (void)
455 {
456 }
457
458 void ShaderStateQueryTests::init (void)
459 {
460         addChild(new CoreSamplerTypeCase                        (m_context, "sampler_type",                                             "Sampler type cases"));
461         addChild(new MSArraySamplerTypeCase                     (m_context, "sampler_type_multisample_array",   "MSAA array sampler type cases"));
462         addChild(new TextureBufferSamplerTypeCase       (m_context, "sampler_type_texture_buffer",              "Texture buffer sampler type cases"));
463         addChild(new TextureBufferImageTypeCase         (m_context, "image_type_texture_buffer",                "Texture buffer image type cases"));
464         addChild(new CubeArraySamplerTypeCase           (m_context, "sampler_type_cube_array",                  "Cube array sampler type cases"));
465         addChild(new CubeArrayImageTypeCase                     (m_context, "image_type_cube_array",                    "Cube array image type cases"));
466
467         // shader info log tests
468         // \note, there exists similar tests in gles3 module. However, the gles31 could use a different
469         //        shader compiler with different INFO_LOG bugs.
470         {
471                 static const struct
472                 {
473                         const char*             caseName;
474                         glu::ShaderType caseType;
475                 } shaderTypes[] =
476                 {
477                         { "info_log_vertex",            glu::SHADERTYPE_VERTEX                                  },
478                         { "info_log_fragment",          glu::SHADERTYPE_FRAGMENT                                },
479                         { "info_log_geometry",          glu::SHADERTYPE_GEOMETRY                                },
480                         { "info_log_tess_ctrl",         glu::SHADERTYPE_TESSELLATION_CONTROL    },
481                         { "info_log_tess_eval",         glu::SHADERTYPE_TESSELLATION_EVALUATION },
482                         { "info_log_compute",           glu::SHADERTYPE_COMPUTE                                 },
483                 };
484
485                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx)
486                         addChild(new ShaderLogCase(m_context, shaderTypes[ndx].caseName, "", shaderTypes[ndx].caseType));
487         }
488 }
489
490 } // Functional
491 } // gles31
492 } // deqp