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