• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 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 struct tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fShaderFunctionTests.hpp"
25 #include "glsShaderRenderCase.hpp"
26 #include "gluTexture.hpp"
27 #include "tcuStringTemplate.hpp"
28 #include "tcuTextureUtil.hpp"
29 
30 using namespace deqp::gls;
31 
32 namespace deqp
33 {
34 namespace gles3
35 {
36 namespace Functional
37 {
38 
39 typedef void (*SetupUniformsFunc) (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords);
40 
41 class ShaderFunctionCase : public ShaderRenderCase
42 {
43 public:
44 						ShaderFunctionCase		(Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, const char* fragShaderSource);
45 						~ShaderFunctionCase		(void);
46 
47 	void				init					(void);
48 	void				deinit					(void);
49 
50 	virtual void		setupUniforms			(int programID, const tcu::Vec4& constCoords);
51 
52 private:
53 						ShaderFunctionCase		(const ShaderFunctionCase&);
54 	ShaderFunctionCase&	operator=				(const ShaderFunctionCase&);
55 
56 	SetupUniformsFunc	m_setupUniforms;
57 	bool				m_usesTexture;
58 
59 	glu::Texture2D*		m_brickTexture;
60 };
61 
ShaderFunctionCase(Context & context,const char * name,const char * description,bool isVertexCase,bool usesTextures,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniformsFunc,const char * vertShaderSource,const char * fragShaderSource)62 ShaderFunctionCase::ShaderFunctionCase (Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, const char* fragShaderSource)
63 	: ShaderRenderCase	(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
64 	, m_setupUniforms	(setupUniformsFunc)
65 	, m_usesTexture		(usesTextures)
66 	, m_brickTexture	(DE_NULL)
67 {
68 	m_vertShaderSource	= vertShaderSource;
69 	m_fragShaderSource	= fragShaderSource;
70 }
71 
~ShaderFunctionCase(void)72 ShaderFunctionCase::~ShaderFunctionCase (void)
73 {
74 	delete m_brickTexture;
75 }
76 
init(void)77 void ShaderFunctionCase::init (void)
78 {
79 	if (m_usesTexture)
80 	{
81 		m_brickTexture = glu::Texture2D::create(m_renderCtx, m_ctxInfo, m_testCtx.getArchive(), "data/brick.png");
82 		m_textures.push_back(TextureBinding(m_brickTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
83 																		 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR)));
84 		DE_ASSERT(m_textures.size() == 1);
85 	}
86 	gls::ShaderRenderCase::init();
87 }
88 
deinit(void)89 void ShaderFunctionCase::deinit (void)
90 {
91 	gls::ShaderRenderCase::deinit();
92 	delete m_brickTexture;
93 	m_brickTexture = DE_NULL;
94 }
95 
setupUniforms(int programID,const tcu::Vec4 & constCoords)96 void ShaderFunctionCase::setupUniforms (int programID, const tcu::Vec4& constCoords)
97 {
98 	ShaderRenderCase::setupUniforms(programID, constCoords);
99 	if (m_setupUniforms)
100 		m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
101 }
102 
createStructCase(Context & context,const char * name,const char * description,bool isVertexCase,bool usesTextures,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniforms,const LineStream & shaderSrc,const std::map<std::string,std::string> * additionalParams)103 static ShaderFunctionCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc, const std::map<std::string, std::string>* additionalParams)
104 {
105 	static const char* defaultVertSrc =
106 		"#version 300 es\n"
107 		"in highp vec4 a_position;\n"
108 		"in highp vec4 a_coords;\n"
109 		"out mediump vec4 v_coords;\n\n"
110 		"void main (void)\n"
111 		"{\n"
112 		"	v_coords = a_coords;\n"
113 		"	gl_Position = a_position;\n"
114 		"}\n";
115 	static const char* defaultFragSrc =
116 		"#version 300 es\n"
117 		"in mediump vec4 v_color;\n"
118 		"layout(location = 0) out mediump vec4 o_color;\n\n"
119 		"void main (void)\n"
120 		"{\n"
121 		"	o_color = v_color;\n"
122 		"}\n";
123 
124 	// Fill in specialization parameters.
125 	std::map<std::string, std::string> spParams;
126 	if (isVertexCase)
127 	{
128 		spParams["HEADER"] =
129 			"#version 300 es\n"
130 			"in highp vec4 a_position;\n"
131 			"in highp vec4 a_coords;\n"
132 			"out mediump vec4 v_color;";
133 		spParams["COORDS"]		= "a_coords";
134 		spParams["DST"]			= "v_color";
135 		spParams["ASSIGN_POS"]	= "gl_Position = a_position;";
136 	}
137 	else
138 	{
139 		spParams["HEADER"]	=
140 			"#version 300 es\n"
141 			"precision mediump float;\n"
142 			"in mediump vec4 v_coords;\n"
143 			"layout(location = 0) out mediump vec4 o_color;";
144 		spParams["COORDS"]			= "v_coords";
145 		spParams["DST"]				= "o_color";
146 		spParams["ASSIGN_POS"]		= "";
147 	}
148 	if (additionalParams)
149 		spParams.insert(additionalParams->begin(), additionalParams->end());
150 
151 	if (isVertexCase)
152 		return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc);
153 	else
154 		return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, defaultVertSrc, tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
155 }
156 
ShaderFunctionTests(Context & context)157 ShaderFunctionTests::ShaderFunctionTests (Context& context)
158 	: TestCaseGroup(context, "function", "Function Tests")
159 {
160 }
161 
~ShaderFunctionTests(void)162 ShaderFunctionTests::~ShaderFunctionTests (void)
163 {
164 }
165 
init(void)166 void ShaderFunctionTests::init (void)
167 {
168 	#define FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, PARAMS)												\
169 		do {																																	\
170 			struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY };	/* NOLINT(EVAL_FUNC_BODY) */						\
171 			addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, false, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));	\
172 			addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, false,&Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));\
173 		} while (deGetFalse())
174 
175 	#define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \
176 		FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL)
177 
178 	FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable",
179 		LineStream()
180 		<< "${HEADER}"
181 		<< ""
182 		<< "bool out_params_are_distinct(float x, out float y) {"
183 		<< "    y = 2.;"
184 		<< "    return x == 1. && y == 2.;"
185 		<< "}"
186 		<< ""
187 		<< "void main (void)"
188 		<< "{"
189 		<< "    float x = 1.;"
190 		<< "    ${DST} = out_params_are_distinct(x, x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
191 		<< "	${ASSIGN_POS}"
192 		<< "}",
193 		{ c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
194 
195 	FUNCTION_CASE(global_variable_aliasing, "Function out parameter aliases global variable",
196 		LineStream()
197 		<< "${HEADER}"
198 		<< ""
199 		<< ""
200 		<< "float x = 1.;"
201 		<< "bool out_params_are_distinct_from_global(out float y) {"
202 		<< "    y = 2.;"
203 		<< "    return x == 1. && y == 2.;"
204 		<< "}"
205 		<< ""
206 		<< "void main (void)"
207 		<< "{"
208 		<< "    ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
209 		<< "	${ASSIGN_POS}"
210 		<< "}",
211 		{ c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
212 }
213 
214 } // Functional
215 } // gles3
216 } // deqp
217