Add new framebuffer fetch extension tests am: 2a609fb223
[platform/upstream/VK-GL-CTS.git] / modules / gles2 / functional / es2fShaderAlgorithmTests.cpp
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 Algorithm implementation tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "es2fShaderAlgorithmTests.hpp"
25 #include "glsShaderRenderCase.hpp"
26 #include "gluShaderUtil.hpp"
27 #include "tcuStringTemplate.hpp"
28
29 #include "deInt32.h"
30 #include "deMemory.h"
31
32 #include <map>
33 #include <algorithm>
34
35 using namespace std;
36 using namespace tcu;
37 using namespace glu;
38 using namespace deqp::gls;
39
40 namespace deqp
41 {
42 namespace gles2
43 {
44 namespace Functional
45 {
46
47 // ShaderAlgorithmCase
48
49 class ShaderAlgorithmCase : public ShaderRenderCase
50 {
51 public:
52                                                                 ShaderAlgorithmCase                     (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource);
53         virtual                                         ~ShaderAlgorithmCase            (void);
54
55 private:
56                                                                 ShaderAlgorithmCase                     (const ShaderAlgorithmCase&);   // not allowed!
57         ShaderAlgorithmCase&            operator=                                       (const ShaderAlgorithmCase&);   // not allowed!
58 };
59
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)
62 {
63         m_vertShaderSource      = vertShaderSource;
64         m_fragShaderSource      = fragShaderSource;
65 }
66
67 ShaderAlgorithmCase::~ShaderAlgorithmCase (void)
68 {
69 }
70
71 // Helpers.
72
73 static ShaderAlgorithmCase* createExpressionCase (Context& context, const char* caseName, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, LineStream& shaderBody)
74 {
75         std::ostringstream vtx;
76         std::ostringstream frag;
77         std::ostringstream& op = isVertexCase ? vtx : frag;
78
79         vtx << "attribute highp vec4 a_position;\n";
80         vtx << "attribute highp vec4 a_unitCoords;\n";
81
82         if (isVertexCase)
83         {
84                 vtx << "varying mediump vec3 v_color;\n";
85                 frag << "varying mediump vec3 v_color;\n";
86         }
87         else
88         {
89                 vtx << "varying mediump vec4 v_coords;\n";
90                 frag << "varying mediump vec4 v_coords;\n";
91         }
92
93 //      op << "uniform mediump sampler2D ut_brick;\n";
94
95         vtx << "\n";
96         vtx << "void main()\n";
97         vtx << "{\n";
98         vtx << "        gl_Position = a_position;\n";
99
100         frag << "\n";
101         frag << "void main()\n";
102         frag << "{\n";
103
104         // Write matrix.
105         if (isVertexCase)
106                 op << " ${PRECISION} vec4 coords = a_unitCoords;\n";
107         else
108                 op << " ${PRECISION} vec4 coords = v_coords;\n";
109
110         op << " ${PRECISION} vec3 res = vec3(0.0);\n";
111         op << shaderBody.str();
112
113         if (isVertexCase)
114         {
115                 vtx << "        v_color = res;\n";
116                 frag << "       gl_FragColor = vec4(v_color, 1.0);\n";
117         }
118         else
119         {
120                 vtx << "        v_coords = a_unitCoords;\n";
121                 frag << "       gl_FragColor = vec4(res, 1.0);\n";
122         }
123
124         vtx << "}\n";
125         frag << "}\n";
126
127         // Fill in shader templates.
128         map<string, string> params;
129         params.insert(pair<string, string>("PRECISION", "mediump"));
130
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);
135
136         return new ShaderAlgorithmCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
137 }
138
139 // ShaderAlgorithmTests.
140
141 ShaderAlgorithmTests::ShaderAlgorithmTests(Context& context)
142         : TestCaseGroup(context, "algorithm", "Miscellaneous algorithm implementations using shaders.")
143 {
144 }
145
146 ShaderAlgorithmTests::~ShaderAlgorithmTests (void)
147 {
148 }
149
150 void ShaderAlgorithmTests::init (void)
151 {
152 //      TestCaseGroup* colorGroup = new TestCaseGroup(m_testCtx, "color", "Miscellaneous color related algorithm tests.");
153 //      addChild(colorGroup);
154
155         #define SHADER_OP_CASE(NAME, DESCRIPTION, SHADER_OP, EVAL_FUNC_BODY)                                                                                                            \
156                 do {                                                                                                                                                                                                                                    \
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())
161
162         SHADER_OP_CASE(hsl_to_rgb, "Conversion from HSL color space into RGB.",
163                 LineStream(1)
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"
167                 << "if (v > 0.0)"
168                 << "{"
169                 << "    mediump float m = L + L - v;"
170                 << "    mediump float sv = (v - m) / v;"
171                 << "    H *= 6.0;"
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);"
183                 << "}",
184                 {
185                         float H = c.unitCoords.x();
186                         float S = c.unitCoords.y();
187                         float L = c.unitCoords.z();
188                         Vec3 rgb = Vec3(L);
189                         float v = (L <= 0.5f) ? (L * (1.0f + S)) : (L + S - L * S);
190                         if (v > 0.0f)
191                         {
192                                 float m = L + L - v;
193                                 float sv = (v - m) / v;
194                                 H *= 6.0f;
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);
206                         }
207                         c.color.xyz() = rgb;
208                 });
209
210         SHADER_OP_CASE(rgb_to_hsl, "Conversion from RGB color space into HSL.",
211                 LineStream(1)
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);"
218                 << "else"
219                 << "{"
220                 << "    mediump float H;"
221                 << "    mediump float S;"
222                 << "    if (L < 0.5)"
223                 << "            S = (maxVal - minVal) / (maxVal + minVal);"
224                 << "    else"
225                 << "            S = (maxVal - minVal) / (2.0 - maxVal - minVal);"
226                 << ""
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;"
231                 << "    H /= 6.0;"
232                 << ""
233                 << "    res = vec3(H, S, L);"
234                 << "}",
235                 {
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;
242                         Vec3 hsl;
243
244                         if (minVal == maxVal)
245                                 hsl = Vec3(0.0f, 0.0f, L);
246                         else
247                         {
248                                 float H;
249                                 float S;
250                                 if (L < 0.5f)
251                                         S = (maxVal - minVal) / (maxVal + minVal);
252                                 else
253                                         S = (maxVal - minVal) / (2.0f - maxVal - minVal);
254
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;
259                                 H /= 6.0f;
260
261                                 hsl = Vec3(H, S, L);
262                         }
263                         c.color.xyz() = hsl;
264                 });
265
266 /*      SHADER_OP_CASE(image_to_grayscale, "Convert image to grayscale.",
267                 LineStream(1)
268                 << "res = texture2D(ut_brick, coords.xy).rgb;",
269                 {
270                         c.color.xyz() = Vec3(0.5f);
271                 });*/
272 }
273
274 } // Functional
275 } // gles2
276 } // deqp