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