• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2016 Google Inc.
6  * Copyright (c) 2016 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */ /*!
21  * \file
22  * \brief Shader struct tests.
23  */ /*-------------------------------------------------------------------*/
24 
25 #include "glcShaderFunctionTests.hpp"
26 #include "glcShaderRenderCase.hpp"
27 #include "gluTexture.hpp"
28 #include "tcuStringTemplate.hpp"
29 #include "tcuTextureUtil.hpp"
30 
31 using namespace glu;
32 
33 namespace deqp
34 {
35 
36 typedef void (*SetupUniformsFunc)(const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords);
37 
38 class ShaderFunctionCase : public ShaderRenderCase
39 {
40 public:
41 	ShaderFunctionCase(Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures,
42 					 ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource,
43 					 const char* fragShaderSource);
44 	~ShaderFunctionCase(void);
45 
46 	void init(void);
47 	void deinit(void);
48 
49 	virtual void setupUniforms(deUint32 programID, const tcu::Vec4& constCoords);
50 
51 private:
52 	ShaderFunctionCase(const ShaderFunctionCase&);
53 	ShaderFunctionCase& operator=(const ShaderFunctionCase&);
54 
55 	SetupUniformsFunc m_setupUniforms;
56 	bool			  m_usesTexture;
57 
58 	glu::Texture2D* m_gradientTexture;
59 };
60 
ShaderFunctionCase(Context & context,const char * name,const char * description,bool isVertexCase,bool usesTextures,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniformsFunc,const char * vertShaderSource,const char * fragShaderSource)61 ShaderFunctionCase::ShaderFunctionCase(Context& context, const char* name, const char* description, bool isVertexCase,
62 								   bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc,
63 								   const char* vertShaderSource, const char* fragShaderSource)
64 	: ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
65 					   description, isVertexCase, evalFunc)
66 	, m_setupUniforms(setupUniformsFunc)
67 	, m_usesTexture(usesTextures)
68 	, m_gradientTexture(DE_NULL)
69 {
70 	m_vertShaderSource = vertShaderSource;
71 	m_fragShaderSource = fragShaderSource;
72 }
73 
~ShaderFunctionCase(void)74 ShaderFunctionCase::~ShaderFunctionCase(void)
75 {
76 }
77 
init(void)78 void ShaderFunctionCase::init(void)
79 {
80 	if (m_usesTexture)
81 	{
82 		m_gradientTexture = new glu::Texture2D(m_renderCtx, GL_RGBA8, 128, 128);
83 
84 		m_gradientTexture->getRefTexture().allocLevel(0);
85 		tcu::fillWithComponentGradients(m_gradientTexture->getRefTexture().getLevel(0), tcu::Vec4(0.0f),
86 										tcu::Vec4(1.0f));
87 		m_gradientTexture->upload();
88 
89 		m_textures.push_back(TextureBinding(
90 			m_gradientTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
91 											tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR)));
92 		DE_ASSERT(m_textures.size() == 1);
93 	}
94 	ShaderRenderCase::init();
95 }
96 
deinit(void)97 void ShaderFunctionCase::deinit(void)
98 {
99 	if (m_usesTexture)
100 	{
101 		delete m_gradientTexture;
102 	}
103 	ShaderRenderCase::deinit();
104 }
105 
setupUniforms(deUint32 programID,const tcu::Vec4 & constCoords)106 void ShaderFunctionCase::setupUniforms(deUint32 programID, const tcu::Vec4& constCoords)
107 {
108 	ShaderRenderCase::setupUniforms(programID, constCoords);
109 	if (m_setupUniforms)
110 		m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
111 }
112 
createStructCase(Context & context,const char * name,const char * description,glu::GLSLVersion glslVersion,bool isVertexCase,bool usesTextures,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniforms,const LineStream & shaderSrc)113 static ShaderFunctionCase* createStructCase(Context& context, const char* name, const char* description,
114 										  glu::GLSLVersion glslVersion, bool isVertexCase, bool usesTextures,
115 										  ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms,
116 										  const LineStream& shaderSrc)
117 {
118 	const std::string versionDecl = glu::getGLSLVersionDeclaration(glslVersion);
119 
120 	const std::string defaultVertSrc = versionDecl + "\n"
121 													 "in highp vec4 a_position;\n"
122 													 "in highp vec4 a_coords;\n"
123 													 "out mediump vec4 v_coords;\n\n"
124 													 "void main (void)\n"
125 													 "{\n"
126 													 "   v_coords = a_coords;\n"
127 													 "   gl_Position = a_position;\n"
128 													 "}\n";
129 	const std::string defaultFragSrc = versionDecl + "\n"
130 													 "in mediump vec4 v_color;\n"
131 													 "layout(location = 0) out mediump vec4 o_color;\n\n"
132 													 "void main (void)\n"
133 													 "{\n"
134 													 "   o_color = v_color;\n"
135 													 "}\n";
136 
137 	// Fill in specialization parameters.
138 	std::map<std::string, std::string> spParams;
139 	if (isVertexCase)
140 	{
141 		spParams["HEADER"] = versionDecl + "\n"
142 										   "in highp vec4 a_position;\n"
143 										   "in highp vec4 a_coords;\n"
144 										   "out mediump vec4 v_color;";
145 		spParams["COORDS"]	 = "a_coords";
146 		spParams["DST"]		   = "v_color";
147 		spParams["ASSIGN_POS"] = "gl_Position = a_position;";
148 	}
149 	else
150 	{
151 		spParams["HEADER"] = versionDecl + "\n"
152 										   "#ifdef GL_ES\n"
153 										   "    precision mediump float;\n"
154 										   "#endif\n"
155 										   "\n"
156 										   "in mediump vec4 v_coords;\n"
157 										   "layout(location = 0) out mediump vec4 o_color;";
158 		spParams["COORDS"]	 = "v_coords";
159 		spParams["DST"]		   = "o_color";
160 		spParams["ASSIGN_POS"] = "";
161 	}
162 
163 	if (isVertexCase)
164 		return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
165 									tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(),
166 									defaultFragSrc.c_str());
167 	else
168 		return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
169 									defaultVertSrc.c_str(),
170 									tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
171 }
172 
ShaderFunctionTests(Context & context,glu::GLSLVersion glslVersion)173 ShaderFunctionTests::ShaderFunctionTests(Context& context, glu::GLSLVersion glslVersion)
174 	: TestCaseGroup(context, "function", "Function Tests"), m_glslVersion(glslVersion)
175 {
176 }
177 
~ShaderFunctionTests(void)178 ShaderFunctionTests::~ShaderFunctionTests(void)
179 {
180 }
181 
init(void)182 void ShaderFunctionTests::init(void)
183 {
184 #define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY)                                      \
185 	do                                                                                                    \
186 	{                                                                                                     \
187 		struct Eval_##NAME                                                                                \
188 		{                                                                                                 \
189 			static void eval(ShaderEvalContext& c) EVAL_FUNC_BODY                                         \
190 		};                                                                                                \
191 		addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, m_glslVersion, true, false,    \
192 								  &Eval_##NAME::eval, DE_NULL, SHADER_SRC));                              \
193 		addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, m_glslVersion, false, false, \
194 								  &Eval_##NAME::eval, DE_NULL, SHADER_SRC));                              \
195 	} while (deGetFalse())
196 
197 	FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable",
198 				  LineStream() << "${HEADER}"
199 							   << ""
200 							   << "bool out_params_are_distinct(float x, out float y) {"
201 							   << "    y = 2.;"
202 							   << "    return x == 1. && y == 2.;"
203 							   << "}"
204 							   << ""
205 							   << "void main (void)"
206 							   << "{"
207 							   << "    float x = 1.;"
208 							   << "    ${DST} = out_params_are_distinct(x, 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 	FUNCTION_CASE(global_variable_aliasing, "Function out parameter aliases global variable",
214 				  LineStream() << "${HEADER}"
215 							   << ""
216 							   << "float x = 1.;"
217 							   << "bool out_params_are_distinct_from_global(out float y) {"
218 							   << "    y = 2.;"
219 							   << "    return x == 1. && y == 2.;"
220 							   << "}"
221 							   << ""
222 							   << "void main (void)"
223 							   << "{"
224 							   << "    ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
225 							   << "    ${ASSIGN_POS}"
226 							   << "}",
227 				  { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
228 }
229 
230 } // deqp
231