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