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