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 "tcuTestLog.hpp"
26#include "tcuStringTemplate.hpp"
27#include "gluShaderProgram.hpp"
28#include "gluRenderContext.hpp"
29#include "gluContextInfo.hpp"
30#include "glwFunctions.hpp"
31#include "glwEnums.hpp"
32
33namespace deqp
34{
35namespace gles31
36{
37namespace Functional
38{
39namespace
40{
41
42class SamplerTypeCase : public TestCase
43{
44public:
45					SamplerTypeCase	(Context& ctx, const char* name, const char* desc);
46
47private:
48	IterateResult	iterate			(void);
49};
50
51SamplerTypeCase::SamplerTypeCase (Context& ctx, const char* name, const char* desc)
52	: TestCase(ctx, name, desc)
53{
54}
55
56SamplerTypeCase::IterateResult SamplerTypeCase::iterate (void)
57{
58	static const struct SamplerType
59	{
60		glw::GLenum	glType;
61		const char*	typeStr;
62		const char*	samplePosStr;
63		bool		isArray;
64	} samplerTypes[] =
65	{
66		{ GL_SAMPLER_2D_MULTISAMPLE,						"sampler2DMS",			"ivec2(gl_FragCoord.xy)",	false	},
67		{ GL_INT_SAMPLER_2D_MULTISAMPLE,					"isampler2DMS",			"ivec2(gl_FragCoord.xy)",	false	},
68		{ GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,			"usampler2DMS",			"ivec2(gl_FragCoord.xy)",	false	},
69		{ GL_SAMPLER_2D_MULTISAMPLE_ARRAY,					"sampler2DMSArray",		"ivec3(gl_FragCoord.xyz)",	true	},
70		{ GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,				"isampler2DMSArray",	"ivec3(gl_FragCoord.xyz)",	true	},
71		{ GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,		"usampler2DMSArray",	"ivec3(gl_FragCoord.xyz)",	true	},
72	};
73
74	static const char* const	vertexSource			=	"#version 310 es\n"
75															"in highp vec4 a_position;\n"
76															"void main(void)\n"
77															"{\n"
78															"	gl_Position = a_position;\n"
79															"}\n";
80	static const char* const	fragmentSourceTemplate	=	"#version 310 es\n"
81															"${EXTENSIONSTATEMENT}"
82															"uniform highp ${SAMPLERTYPE} u_sampler;\n"
83															"layout(location = 0) out highp vec4 dEQP_FragColor;\n"
84															"void main(void)\n"
85															"{\n"
86															"	dEQP_FragColor = vec4(texelFetch(u_sampler, ${POSITION}, 0));\n"
87															"}\n";
88	const bool					textureArraySupported	=	m_context.getContextInfo().isExtensionSupported("GL_OES_texture_storage_multisample_2d_array");
89	bool						error					=	false;
90
91	for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(samplerTypes); ++typeNdx)
92	{
93		const tcu::ScopedLogSection section(m_testCtx.getLog(), std::string(samplerTypes[typeNdx].typeStr), std::string() + "Sampler type " + samplerTypes[typeNdx].typeStr);
94
95		if (samplerTypes[typeNdx].isArray && !textureArraySupported)
96		{
97			m_testCtx.getLog() << tcu::TestLog::Message << "GL_OES_texture_storage_multisample_2d_array not supported, skipping type " << samplerTypes[typeNdx].typeStr << tcu::TestLog::EndMessage;
98		}
99		else
100		{
101			std::map<std::string, std::string>	shaderArgs;
102			shaderArgs["SAMPLERTYPE"]			= samplerTypes[typeNdx].typeStr;
103			shaderArgs["POSITION"]				= samplerTypes[typeNdx].samplePosStr;
104			shaderArgs["EXTENSIONSTATEMENT"]	= (samplerTypes[typeNdx].isArray) ? ("#extension GL_OES_texture_storage_multisample_2d_array : require\n") : ("");
105
106			{
107				const std::string			fragmentSource	= tcu::StringTemplate(fragmentSourceTemplate).specialize(shaderArgs);
108				const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
109				glu::ShaderProgram			program			(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(vertexSource) << glu::FragmentSource(fragmentSource));
110
111				m_testCtx.getLog() << tcu::TestLog::Message << "Building program with uniform sampler of type " << samplerTypes[typeNdx].typeStr << tcu::TestLog::EndMessage;
112
113				if (!program.isOk())
114				{
115					m_testCtx.getLog() << program;
116					throw tcu::TestError("could not build shader");
117				}
118
119				// only one uniform -- uniform at index 0
120				{
121					int uniforms = 0;
122					gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORMS, &uniforms);
123
124					if (uniforms != 1)
125						throw tcu::TestError("Unexpected GL_ACTIVE_UNIFORMS, expected 1");
126				}
127
128				m_testCtx.getLog() << tcu::TestLog::Message << "Verifying uniform type." << tcu::TestLog::EndMessage;
129
130				// check type
131				{
132					const glw::GLuint	uniformIndex	= 0;
133					glw::GLint			type			= 0;
134
135					gl.getActiveUniformsiv(program.getProgram(), 1, &uniformIndex, GL_UNIFORM_TYPE, &type);
136
137					if (type != (glw::GLint)samplerTypes[typeNdx].glType)
138					{
139						m_testCtx.getLog() << tcu::TestLog::Message << "Invalid type, expected " << samplerTypes[typeNdx].glType << ", got " << type << tcu::TestLog::EndMessage;
140						error = true;
141					}
142				}
143
144				GLU_EXPECT_NO_ERROR(gl.getError(), "");
145			}
146		}
147	}
148
149	if (!error)
150		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
151	else
152		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid uniform type");
153
154	return STOP;
155}
156
157} // anonymous
158
159ShaderStateQueryTests::ShaderStateQueryTests (Context& context)
160	: TestCaseGroup(context, "shader", "Shader state query tests")
161{
162}
163
164ShaderStateQueryTests::~ShaderStateQueryTests (void)
165{
166}
167
168void ShaderStateQueryTests::init (void)
169{
170	// sampler type query
171	addChild(new SamplerTypeCase(m_context, "sampler_type", "Sampler type cases"));
172}
173
174} // Functional
175} // gles31
176} // deqp
177