1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Algorithm implementation tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es2fShaderAlgorithmTests.hpp"
25 #include "glsShaderRenderCase.hpp"
26 #include "gluShaderUtil.hpp"
27 #include "tcuStringTemplate.hpp"
38 using namespace deqp::gls;
47 // ShaderAlgorithmCase
49 class ShaderAlgorithmCase : public ShaderRenderCase
52 ShaderAlgorithmCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource);
53 virtual ~ShaderAlgorithmCase (void);
56 ShaderAlgorithmCase (const ShaderAlgorithmCase&); // not allowed!
57 ShaderAlgorithmCase& operator= (const ShaderAlgorithmCase&); // not allowed!
60 ShaderAlgorithmCase::ShaderAlgorithmCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource)
61 : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
63 m_vertShaderSource = vertShaderSource;
64 m_fragShaderSource = fragShaderSource;
67 ShaderAlgorithmCase::~ShaderAlgorithmCase (void)
73 static ShaderAlgorithmCase* createExpressionCase (Context& context, const char* caseName, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, LineStream& shaderBody)
75 std::ostringstream vtx;
76 std::ostringstream frag;
77 std::ostringstream& op = isVertexCase ? vtx : frag;
79 vtx << "attribute highp vec4 a_position;\n";
80 vtx << "attribute highp vec4 a_unitCoords;\n";
84 vtx << "varying mediump vec3 v_color;\n";
85 frag << "varying mediump vec3 v_color;\n";
89 vtx << "varying mediump vec4 v_coords;\n";
90 frag << "varying mediump vec4 v_coords;\n";
93 // op << "uniform mediump sampler2D ut_brick;\n";
96 vtx << "void main()\n";
98 vtx << " gl_Position = a_position;\n";
101 frag << "void main()\n";
106 op << " ${PRECISION} vec4 coords = a_unitCoords;\n";
108 op << " ${PRECISION} vec4 coords = v_coords;\n";
110 op << " ${PRECISION} vec3 res = vec3(0.0);\n";
111 op << shaderBody.str();
115 vtx << " v_color = res;\n";
116 frag << " gl_FragColor = vec4(v_color, 1.0);\n";
120 vtx << " v_coords = a_unitCoords;\n";
121 frag << " gl_FragColor = vec4(res, 1.0);\n";
127 // Fill in shader templates.
128 map<string, string> params;
129 params.insert(pair<string, string>("PRECISION", "mediump"));
131 StringTemplate vertTemplate(vtx.str().c_str());
132 StringTemplate fragTemplate(frag.str().c_str());
133 string vertexShaderSource = vertTemplate.specialize(params);
134 string fragmentShaderSource = fragTemplate.specialize(params);
136 return new ShaderAlgorithmCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
139 // ShaderAlgorithmTests.
141 ShaderAlgorithmTests::ShaderAlgorithmTests(Context& context)
142 : TestCaseGroup(context, "algorithm", "Miscellaneous algorithm implementations using shaders.")
146 ShaderAlgorithmTests::~ShaderAlgorithmTests (void)
150 void ShaderAlgorithmTests::init (void)
152 // TestCaseGroup* colorGroup = new TestCaseGroup(m_testCtx, "color", "Miscellaneous color related algorithm tests.");
153 // addChild(colorGroup);
155 #define SHADER_OP_CASE(NAME, DESCRIPTION, SHADER_OP, EVAL_FUNC_BODY) \
157 struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \
158 addChild(createExpressionCase(m_context, #NAME "_vertex", DESCRIPTION, true, &Eval_##NAME::eval, SHADER_OP)); \
159 addChild(createExpressionCase(m_context, #NAME "_fragment", DESCRIPTION, false, &Eval_##NAME::eval, SHADER_OP)); \
160 } while (deGetFalse())
162 SHADER_OP_CASE(hsl_to_rgb, "Conversion from HSL color space into RGB.",
164 << "mediump float H = coords.x, S = coords.y, L = coords.z;"
165 << "mediump float v = (L <= 0.5) ? (L * (1.0 + S)) : (L + S - L * S);"
166 << "res = vec3(L); // default to gray"
169 << " mediump float m = L + L - v;"
170 << " mediump float sv = (v - m) / v;"
172 << " mediump int sextant = int(H);"
173 << " mediump float fract = H - float(sextant);"
174 << " mediump float vsf = v * sv * fract;"
175 << " mediump float mid1 = m + vsf;"
176 << " mediump float mid2 = m - vsf;"
177 << " if (sextant == 0) res = vec3(v, mid1, m);"
178 << " else if (sextant == 1) res = vec3(mid2, v, m);"
179 << " else if (sextant == 2) res = vec3(m, v, mid1);"
180 << " else if (sextant == 3) res = vec3(m, mid2, v);"
181 << " else if (sextant == 4) res = vec3(mid1, m, v);"
182 << " else res = vec3(v, m, mid2);"
185 float H = c.unitCoords.x();
186 float S = c.unitCoords.y();
187 float L = c.unitCoords.z();
189 float v = (L <= 0.5f) ? (L * (1.0f + S)) : (L + S - L * S);
193 float sv = (v - m) / v;
195 int sextant = int(H);
196 float fract = H - float(sextant);
197 float vsf = v * sv * fract;
198 float mid1 = m + vsf;
199 float mid2 = m - vsf;
200 if (sextant == 0) rgb = Vec3(v, mid1, m);
201 else if (sextant == 1) rgb = Vec3(mid2, v, m);
202 else if (sextant == 2) rgb = Vec3(m, v, mid1);
203 else if (sextant == 3) rgb = Vec3(m, mid2, v);
204 else if (sextant == 4) rgb = Vec3(mid1, m, v);
205 else rgb = Vec3(v, m, mid2);
210 SHADER_OP_CASE(rgb_to_hsl, "Conversion from RGB color space into HSL.",
212 << "mediump float r = coords.x, g = coords.y, b = coords.z;"
213 << "mediump float minVal = min(min(r, g), b);"
214 << "mediump float maxVal = max(max(r, g), b);"
215 << "mediump float L = (minVal + maxVal) * 0.5;"
216 << "if (minVal == maxVal)"
217 << " res = vec3(0.0, 0.0, L);"
220 << " mediump float H;"
221 << " mediump float S;"
223 << " S = (maxVal - minVal) / (maxVal + minVal);"
225 << " S = (maxVal - minVal) / (2.0 - maxVal - minVal);"
227 << " mediump float ooDiff = 1.0 / (maxVal - minVal);"
228 << " if (r == maxVal) H = (g - b) * ooDiff;"
229 << " else if (g == maxVal) H = 2.0 + (b - r) * ooDiff;"
230 << " else H = 4.0 + (r - g) * ooDiff;"
233 << " res = vec3(H, S, L);"
236 float r = c.unitCoords.x();
237 float g = c.unitCoords.y();
238 float b = c.unitCoords.z();
239 float minVal = min(min(r, g), b);
240 float maxVal = max(max(r, g), b);
241 float L = (minVal + maxVal) * 0.5f;
244 if (minVal == maxVal)
245 hsl = Vec3(0.0f, 0.0f, L);
251 S = (maxVal - minVal) / (maxVal + minVal);
253 S = (maxVal - minVal) / (2.0f - maxVal - minVal);
255 float ooDiff = 1.0f / (maxVal - minVal);
256 if (r == maxVal) H = (g - b) * ooDiff;
257 else if (g == maxVal) H = 2.0f + (b - r) * ooDiff;
258 else H = 4.0f + (r - g) * ooDiff;
266 /* SHADER_OP_CASE(image_to_grayscale, "Convert image to grayscale.",
268 << "res = texture2D(ut_brick, coords.xy).rgb;",
270 c.color.xyz() = Vec3(0.5f);