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