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