1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Shader state query tests
22 *//*--------------------------------------------------------------------*/
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"
46 static inline std::string brokenShaderSource (const glu::ContextType &contextType)
48 const std::string glslVersionDecl = glu::getGLSLVersionDeclaration(glu::getContextTypeGLSLVersion(contextType));
50 return glslVersionDecl + "\n"
51 "broken, this should not compile,\n"
55 class BaseTypeCase : public TestCase
61 const char* declarationStr;
62 const char* accessStr;
65 BaseTypeCase (Context& ctx, const char* name, const char* desc, const char* extension);
68 IterateResult iterate (void);
69 virtual std::vector<TestTypeInfo> getInfos (void) const = 0;
70 virtual void checkRequirements (void) const;
72 const char* const m_extension;
75 BaseTypeCase::BaseTypeCase (Context& ctx, const char* name, const char* desc, const char* extension)
76 : TestCase (ctx, name, desc)
77 , m_extension (extension)
81 BaseTypeCase::IterateResult BaseTypeCase::iterate (void)
83 static const char* const vertexSourceTemplate = "${VERSIONDECL}\n"
84 "in highp vec4 a_position;\n"
87 " gl_Position = a_position;\n"
89 static const char* const fragmentSourceTemplate = "${VERSIONDECL}\n"
90 "${EXTENSIONSTATEMENT}"
91 "${DECLARATIONSTR};\n"
92 "layout(location = 0) out highp vec4 dEQP_FragColor;\n"
95 " dEQP_FragColor = vec4(${ACCESSSTR});\n"
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));
104 if (m_extension && !isES32orGL45 && !m_context.getContextInfo().isExtensionSupported(m_extension))
105 throw tcu::NotSupportedError("Test requires " + std::string(m_extension));
108 for (int typeNdx = 0; typeNdx < (int)samplerTypes.size(); ++typeNdx)
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());
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));
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));
125 m_testCtx.getLog() << tcu::TestLog::Message << "Building program with uniform sampler of type " << glu::getShaderVarTypeStr(samplerTypes[typeNdx].glType) << tcu::TestLog::EndMessage;
129 m_testCtx.getLog() << program;
130 result.fail("could not build shader");
134 // only one uniform -- uniform at index 0
136 gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORMS, &uniforms);
139 result.fail("Unexpected GL_ACTIVE_UNIFORMS, expected 1");
143 const glw::GLuint uniformIndex = 0;
146 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying uniform type." << tcu::TestLog::EndMessage;
147 gl.getActiveUniformsiv(program.getProgram(), 1, &uniformIndex, GL_UNIFORM_TYPE, &type);
149 if (type != (glw::GLint)samplerTypes[typeNdx].glType)
151 std::ostringstream buf;
152 buf << "Invalid type, expected " << samplerTypes[typeNdx].glType << ", got " << type;
153 result.fail(buf.str());
158 GLU_EXPECT_NO_ERROR(gl.getError(), "");
161 result.setTestContextResult(m_testCtx);
165 void BaseTypeCase::checkRequirements (void) const
169 class CoreSamplerTypeCase : public BaseTypeCase
172 CoreSamplerTypeCase (Context& ctx, const char* name, const char* desc);
175 std::vector<TestTypeInfo> getInfos (void) const;
178 CoreSamplerTypeCase::CoreSamplerTypeCase (Context& ctx, const char* name, const char* desc)
179 : BaseTypeCase(ctx, name, desc, DE_NULL)
183 std::vector<BaseTypeCase::TestTypeInfo> CoreSamplerTypeCase::getInfos (void) const
185 static const TestTypeInfo samplerTypes[] =
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)" },
192 std::vector<TestTypeInfo> infos;
193 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
194 infos.push_back(samplerTypes[ndx]);
199 class MSArraySamplerTypeCase : public BaseTypeCase
202 MSArraySamplerTypeCase (Context& ctx, const char* name, const char* desc);
205 std::vector<TestTypeInfo> getInfos (void) const;
208 MSArraySamplerTypeCase::MSArraySamplerTypeCase (Context& ctx, const char* name, const char* desc)
209 : BaseTypeCase(ctx, name, desc, "GL_OES_texture_storage_multisample_2d_array")
213 std::vector<BaseTypeCase::TestTypeInfo> MSArraySamplerTypeCase::getInfos (void) const
215 static const TestTypeInfo samplerTypes[] =
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)" },
222 std::vector<TestTypeInfo> infos;
223 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
224 infos.push_back(samplerTypes[ndx]);
229 class TextureBufferSamplerTypeCase : public BaseTypeCase
232 TextureBufferSamplerTypeCase (Context& ctx, const char* name, const char* desc);
235 std::vector<TestTypeInfo> getInfos (void) const;
238 TextureBufferSamplerTypeCase::TextureBufferSamplerTypeCase (Context& ctx, const char* name, const char* desc)
239 : BaseTypeCase(ctx, name, desc, "GL_EXT_texture_buffer")
243 std::vector<BaseTypeCase::TestTypeInfo> TextureBufferSamplerTypeCase::getInfos (void) const
245 static const TestTypeInfo samplerTypes[] =
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))" },
252 std::vector<TestTypeInfo> infos;
253 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
254 infos.push_back(samplerTypes[ndx]);
259 class TextureBufferImageTypeCase : public BaseTypeCase
262 TextureBufferImageTypeCase (Context& ctx, const char* name, const char* desc);
265 std::vector<TestTypeInfo> getInfos (void) const;
266 void checkRequirements (void) const;
269 TextureBufferImageTypeCase::TextureBufferImageTypeCase (Context& ctx, const char* name, const char* desc)
270 : BaseTypeCase(ctx, name, desc, "GL_EXT_texture_buffer")
274 std::vector<BaseTypeCase::TestTypeInfo> TextureBufferImageTypeCase::getInfos (void) const
276 static const TestTypeInfo samplerTypes[] =
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))" },
283 std::vector<TestTypeInfo> infos;
284 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
285 infos.push_back(samplerTypes[ndx]);
290 void TextureBufferImageTypeCase::checkRequirements (void) const
292 if (m_context.getContextInfo().getInt(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) < 1)
293 throw tcu::NotSupportedError("Test requires fragment images");
296 class CubeArraySamplerTypeCase : public BaseTypeCase
299 CubeArraySamplerTypeCase (Context& ctx, const char* name, const char* desc);
302 std::vector<TestTypeInfo> getInfos (void) const;
305 CubeArraySamplerTypeCase::CubeArraySamplerTypeCase (Context& ctx, const char* name, const char* desc)
306 : BaseTypeCase(ctx, name, desc, "GL_EXT_texture_cube_map_array")
310 std::vector<BaseTypeCase::TestTypeInfo> CubeArraySamplerTypeCase::getInfos (void) const
312 static const TestTypeInfo samplerTypes[] =
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)" },
320 std::vector<TestTypeInfo> infos;
321 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
322 infos.push_back(samplerTypes[ndx]);
327 class CubeArrayImageTypeCase : public BaseTypeCase
330 CubeArrayImageTypeCase (Context& ctx, const char* name, const char* desc);
333 std::vector<TestTypeInfo> getInfos (void) const;
334 void checkRequirements (void) const;
337 CubeArrayImageTypeCase::CubeArrayImageTypeCase (Context& ctx, const char* name, const char* desc)
338 : BaseTypeCase(ctx, name, desc, "GL_EXT_texture_cube_map_array")
342 std::vector<BaseTypeCase::TestTypeInfo> CubeArrayImageTypeCase::getInfos (void) const
344 static const TestTypeInfo samplerTypes[] =
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))" },
351 std::vector<TestTypeInfo> infos;
352 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(samplerTypes); ++ndx)
353 infos.push_back(samplerTypes[ndx]);
358 void CubeArrayImageTypeCase::checkRequirements (void) const
360 if (m_context.getContextInfo().getInt(GL_MAX_FRAGMENT_IMAGE_UNIFORMS) < 1)
361 throw tcu::NotSupportedError("Test requires fragment images");
364 class ShaderLogCase : public TestCase
367 ShaderLogCase (Context& ctx, const char* name, const char* desc, glu::ShaderType shaderType);
371 IterateResult iterate (void);
373 const glu::ShaderType m_shaderType;
376 ShaderLogCase::ShaderLogCase (Context& ctx, const char* name, const char* desc, glu::ShaderType shaderType)
377 : TestCase (ctx, name, desc)
378 , m_shaderType (shaderType)
382 void ShaderLogCase::init (void)
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));
388 switch (m_shaderType)
390 case glu::SHADERTYPE_VERTEX:
391 case glu::SHADERTYPE_FRAGMENT:
392 case glu::SHADERTYPE_COMPUTE:
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.");
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.");
412 ShaderLogCase::IterateResult ShaderLogCase::iterate (void)
414 using gls::StateQueryUtil::StateQueryMemoryWriteGuard;
416 tcu::ResultCollector result (m_testCtx.getLog());
417 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
419 const std::string source = brokenShaderSource(m_context.getRenderContext().getType());
420 const char* const brokenSource = source.c_str();
421 StateQueryMemoryWriteGuard<glw::GLint> logLen;
423 gl.enableLogging(true);
425 m_testCtx.getLog() << tcu::TestLog::Message << "Trying to compile broken shader source." << tcu::TestLog::EndMessage;
427 shader = gl.glCreateShader(glu::getGLShaderType(m_shaderType));
428 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "create shader");
430 gl.glShaderSource(shader, 1, &brokenSource, DE_NULL);
431 gl.glCompileShader(shader);
432 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "compile");
434 gl.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLen);
435 logLen.verifyValidity(result);
437 if (!logLen.isUndefined())
438 verifyInfoLogQuery(result, gl, logLen, shader, &glu::CallLogWrapper::glGetShaderInfoLog, "glGetShaderInfoLog");
440 gl.glDeleteShader(shader);
441 GLS_COLLECT_GL_ERROR(result, gl.glGetError(), "delete");
443 result.setTestContextResult(m_testCtx);
449 ShaderStateQueryTests::ShaderStateQueryTests (Context& context)
450 : TestCaseGroup(context, "shader", "Shader state query tests")
454 ShaderStateQueryTests::~ShaderStateQueryTests (void)
458 void ShaderStateQueryTests::init (void)
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"));
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.
473 const char* caseName;
474 glu::ShaderType caseType;
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 },
485 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx)
486 addChild(new ShaderLogCase(m_context, shaderTypes[ndx].caseName, "", shaderTypes[ndx].caseType));