1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.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 "es2fShaderFunctionTests.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 gles2
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, 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 const SetupUniformsFunc m_setupUniforms;
57
58 glu::Texture2D* m_brickTexture;
59 };
60
ShaderFunctionCase(Context & context,const char * name,const char * description,bool isVertexCase,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniformsFunc,const char * vertShaderSource,const char * fragShaderSource)61 ShaderFunctionCase::ShaderFunctionCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, const char* fragShaderSource)
62 : ShaderRenderCase (context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
63 , m_setupUniforms (setupUniformsFunc)
64 , m_brickTexture (DE_NULL)
65 {
66 m_vertShaderSource = vertShaderSource;
67 m_fragShaderSource = fragShaderSource;
68 }
69
~ShaderFunctionCase(void)70 ShaderFunctionCase::~ShaderFunctionCase (void)
71 {
72 delete m_brickTexture;
73 }
74
init(void)75 void ShaderFunctionCase::init (void)
76 {
77 gls::ShaderRenderCase::init();
78 }
79
deinit(void)80 void ShaderFunctionCase::deinit (void)
81 {
82 gls::ShaderRenderCase::deinit();
83 delete m_brickTexture;
84 m_brickTexture = DE_NULL;
85 }
86
setupUniforms(int programID,const tcu::Vec4 & constCoords)87 void ShaderFunctionCase::setupUniforms (int programID, const tcu::Vec4& constCoords)
88 {
89 ShaderRenderCase::setupUniforms(programID, constCoords);
90 if (m_setupUniforms)
91 m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
92 }
93
createStructCase(Context & context,const char * name,const char * description,bool isVertexCase,ShaderEvalFunc evalFunc,SetupUniformsFunc setupUniforms,const LineStream & shaderSrc,const std::map<std::string,std::string> * additionalParams)94 static ShaderFunctionCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc, const std::map<std::string, std::string>* additionalParams)
95 {
96 static const char* defaultVertSrc =
97 "attribute highp vec4 a_position;\n"
98 "attribute highp vec4 a_coords;\n"
99 "varying mediump vec4 v_coords;\n\n"
100 "void main (void)\n"
101 "{\n"
102 " v_coords = a_coords;\n"
103 " gl_Position = a_position;\n"
104 "}\n";
105 static const char* defaultFragSrc =
106 "varying mediump vec4 v_color;\n\n"
107 "void main (void)\n"
108 "{\n"
109 " gl_FragColor = v_color;\n"
110 "}\n";
111
112 // Fill in specialization parameters.
113 std::map<std::string, std::string> spParams;
114 if (isVertexCase)
115 {
116 spParams["DECLARATIONS"] =
117 "attribute highp vec4 a_position;\n"
118 "attribute highp vec4 a_coords;\n"
119 "varying mediump vec4 v_color;";
120 spParams["COORDS"] = "a_coords";
121 spParams["DST"] = "v_color";
122 spParams["ASSIGN_POS"] = "gl_Position = a_position;";
123 }
124 else
125 {
126 spParams["DECLARATIONS"] =
127 "precision highp float;\n"
128 "varying mediump vec4 v_coords;";
129 spParams["COORDS"] = "v_coords";
130 spParams["DST"] = "gl_FragColor";
131 spParams["ASSIGN_POS"] = "";
132 }
133 if (additionalParams)
134 spParams.insert(additionalParams->begin(), additionalParams->end());
135
136 if (isVertexCase)
137 return new ShaderFunctionCase(context, name, description, isVertexCase, evalFunc, setupUniforms, tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc);
138 else
139 return new ShaderFunctionCase(context, name, description, isVertexCase, evalFunc, setupUniforms, defaultVertSrc, tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
140 }
141
ShaderFunctionTests(Context & context)142 ShaderFunctionTests::ShaderFunctionTests (Context& context)
143 : TestCaseGroup(context, "function", "Function Tests")
144 {
145 }
146
~ShaderFunctionTests(void)147 ShaderFunctionTests::~ShaderFunctionTests (void)
148 {
149 }
150
init(void)151 void ShaderFunctionTests::init (void)
152 {
153 #define FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, PARAMS) \
154 do { \
155 struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \
156 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS)); \
157 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));\
158 } while (deGetFalse())
159
160 #define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \
161 FUNCTION_CASE_PARAMETERIZED(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL)
162
163 FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable",
164 LineStream()
165 << "${DECLARATIONS}"
166 << ""
167 << "bool out_params_are_distinct(float x, out float y)"
168 << "{"
169 << " y = 2.;"
170 << " return x == 1. && y == 2.;"
171 << "}"
172 << ""
173 << "void main (void)"
174 << "{"
175 << " float x = 1.;"
176 << " ${DST} = out_params_are_distinct(x, x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
177 << " ${ASSIGN_POS}"
178 << "}",
179 { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
180
181 FUNCTION_CASE(global_variable_aliasing, "Function out parameter aliases global variable",
182 LineStream()
183 << "${DECLARATIONS}"
184 << ""
185 << ""
186 << "float x = 1.;"
187 << "bool out_params_are_distinct_from_global(out float y) {"
188 << " y = 2.;"
189 << " return x == 1. && y == 2.;"
190 << "}"
191 << ""
192 << "void main (void)"
193 << "{"
194 << " ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
195 << " ${ASSIGN_POS}"
196 << "}",
197 { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
198 }
199
200 } // Functional
201 } // gles2
202 } // deqp
203